<!DOCTYPE html><html><head><meta charSet="utf-8" /><meta httpEquiv="x-ua-compatible" content="ie=edge" /><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" /><style data-href="/styles.ce7bb0ac685b9be93cb6.css" data-identity="gatsby-global-css">.ss--accordion{border-top:2px solid #252a25;margin:auto;max-width:90rem;position:relative}.ss--accordion h4{margin:0;text-align:left}@media print,screen and (min-width:64em){.ss--accordion h4{font-size:1.5rem}}.ss--accordion p:last-child{margin:0}.ss--accordion__item{border-bottom:1px solid #252a25;padding:1.25rem 0;position:relative}.ss--block--bg-primary .ss--accordion__item{border-bottom:1px solid var(--block-text-color)}.ss--accordion__content{padding-top:1.25rem}.ss--accordion__header{align-items:center;background:transparent;border:0;display:flex;justify-content:space-between;padding:0 1.25rem 0 0;width:100%}.ss--accordion__icon{align-items:center;border-radius:100%;color:currentColor;display:flex;height:1.875rem;justify-content:center;width:1.875rem}.ss--block--bg-dark .ss--accordion__icon{background-color:var(--block-link-color);color:var(--block-bg)}.ss--accordion__icon svg{font-size:.875rem;height:1em;transform:rotate(90deg);width:1em}.ss--block{position:relative}.ss--block--gutters{padding-left:1.25rem;padding-right:1.25rem}@media screen and (min-width:75em){.ss--block--gutters{padding-left:0;padding-right:0}}.ss--block--bg-gray{background-color:#eff2f2}.ss--block--bg-primary-gradient{background:linear-gradient(216.32794deg,#00bebe,#008a55)}.ss--blockquote blockquote{font-size:1.3125rem;margin:0;padding:1.25rem 0}@media screen and (min-width:49.25em){.ss--blockquote blockquote{padding:1.25rem 1.875rem}}.ss--breadcrumbs{font-size:.875rem;margin:0 auto;max-width:73.125rem;padding:1.25rem 1.25rem 0}@media screen and (min-width:75em){.ss--breadcrumbs{padding:1.25rem 0 0}}.ss--breadcrumbs ul{line-height:1}.ss--breadcrumbs a{color:currentColor;text-decoration:none}.ss--breadcrumbs__list{list-style:none;margin:0 0 2.5rem;padding:0}.ss--breadcrumbs__item{display:inline-block;margin:0 0 .3125rem}.ss--breadcrumbs__item:not(:last-child):after{color:#252a25;content:"/";display:inline-block;padding:0 .5em}:root{--button-text-color:currentColor;--button-bg-color:#2a8e5a;--button-bg-active:#216f46;--button-bg-hover:#247a4e;--button-border-color:currentColor}.ss--button{align-items:center;background:var(--button-bg-color);border:0;border-radius:3px;box-shadow:none;color:var(--button-text-color);cursor:pointer;display:flex;font-family:Monda,sans-serif;font-size:.875rem;font-weight:400;justify-content:center;line-height:normal;overflow:hidden;padding:.6em 1.5em;position:relative;text-align:center;text-decoration:none;text-transform:uppercase;width:100%}@media print,screen and (min-width:43.75em){.ss--button{font-size:1rem;width:-webkit-max-content;width:max-content}}.ss--button:after{background-color:currentColor;content:"";inset:0;opacity:0;position:absolute;transition:background .25s ease,opacity .25s ease}.ss--button:focus:after,.ss--button:hover:after{opacity:.1}.ss--button:active:after{opacity:.2}.ss--button[disabled]{box-shadow:none;opacity:.75;pointer-events:none}.ss--button span{color:var(--button-text-color);pointer-events:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.ss--button__icon{display:block;height:1em;line-height:1;width:1em}.ss--button__icon:first-child{margin-right:.5rem}.ss--button__icon:last-child{margin-left:.5rem}.ss--button--color-primary{--button-text-color:#fff;--button-bg-color:#2a8e5a;--button-bg-active:#216f46;--button-bg-hover:#247a4e;--button-border-color:#2a8e5a}.ss--button--color-secondary{--button-text-color:#fff;--button-bg-color:#252a25;--button-bg-active:#121412;--button-bg-hover:#191c19;--button-border-color:#252a25}.ss--button--color-accent{--button-text-color:#fff;--button-bg-color:#00bfbe;--button-bg-active:#009695;--button-bg-hover:#00a6a5;--button-border-color:transparent}.ss--button--color-white{--button-text-color:#fff;--button-bg-color:transparent;--button-bg-active:rgba(37,42,37,.08);--button-bg-hover:rgba(37,42,37,.05);--button-border-color:#fff}.ss--button--color-default{--button-text-color:#fff;--button-bg-color:#252a25;--button-bg-active:#384038;--button-bg-hover:#384038;--button-border-color:#252a25}.ss--button--style-bordered{--button-text-color:var(--button-border-color);background:none;border:2px solid var(--button-border-color)}.ss--button--style-unstyled{--button-text-color:var(--button-bg-color);background:none;border:none;box-shadow:none;cursor:pointer;display:inline-block;font-family:inherit;font-size:1rem;margin:0;padding:0;position:relative;text-align:left;width:unset}.ss--button--style-unstyled:focus,.ss--button--style-unstyled:hover{background:none;opacity:.85}.ss--button--style-unstyled:active{background:none}.ss--button--style-unstyled:after{display:none}.ss--button--elevated{box-shadow:0 .2px 2.2px rgba(0,0,0,.02),0 .4px 5.3px rgba(0,0,0,.028),0 .8px 10px rgba(0,0,0,.035),0 1.3px 17.9px rgba(0,0,0,.042),0 2.5px 33.4px rgba(0,0,0,.05),0 6px 80px rgba(0,0,0,.07)}.ss--button--alignment-center{margin:1rem auto 0}.ss--button--width-full{width:100%}@media print,screen and (min-width:43.75em){.ss--button--width-full{max-width:20rem}}.ss--button--menu-item{--button-bg-color:transparent;--button-bg-active:transparent;--button-bg-hover:transparent;background:none;border:0;color:currentColor;cursor:pointer;display:inline-block;font-size:1rem;font-weight:400;padding:0;position:relative;text-align:left;text-decoration:none;text-transform:none;width:100%}.ss--button--menu-item:active,.ss--button--menu-item:hover{opacity:.7}.ss--button--menu-item:active:after,.ss--button--menu-item:hover:after{opacity:0}.ss--button--close{left:1rem;position:absolute;top:1rem}.ss--checkbox{display:flex;padding-bottom:1rem}.ss--checkbox input{clip:rect(0,0,0,0)!important;align-items:center;border:0!important;display:flex;height:1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:1px!important}.ss--checkbox label{align-items:flex-start;display:flex;font-size:1rem;text-align:left}.ss--checkbox label svg{color:#2a8e5a;cursor:pointer;margin:0 1rem .125rem 0;min-height:1.25rem;min-width:1.25rem}.ss--checkbox [type=checkbox]{display:block;margin-right:1rem;margin-top:.4rem;min-width:.8rem}.ss--checkbox [type=checkbox]:-ms-input-placeholder{opacity:.4}.ss--checkbox [type=checkbox]::placeholder{opacity:.4}.ss--checkbox__checked{display:flex;position:relative}.ss--checkbox__checked .ss--checkbox__check{bottom:0;left:0;position:absolute;right:0;top:0}.ss--checkbox__checked .ss--checkbox__check svg{color:#252a25}.ss--checkbox--error .ss--checkbox__error{color:#d85d5d}.ss--chip{position:relative}.ss--chip__link.ss--chip__link{background-color:#2a8e5a;border-radius:50em;color:#fff;display:block;font-weight:300;line-height:normal;margin:0;padding:.41667rem 1.25rem;text-align:center;text-decoration:none;transition:background-color .25s ease,opacity .25s ease;white-space:nowrap}.ss--chip__link.ss--chip__link:active,.ss--chip__link.ss--chip__link:hover{background-color:#247a4e;color:#fff}.ss--chip__link.ss--chip__link[aria-current]{background-color:#2a8e5a;color:#fff}.ss--chip__link.ss--chip__link[aria-current]:active,.ss--chip__link.ss--chip__link[aria-current]:hover{background-color:#247a4e}.ss--chip--elevated a{box-shadow:0 .2px 2.2px rgba(0,0,0,.02),0 .4px 5.3px rgba(0,0,0,.028),0 .8px 10px rgba(0,0,0,.035),0 1.3px 17.9px rgba(0,0,0,.042),0 2.5px 33.4px rgba(0,0,0,.05),0 6px 80px rgba(0,0,0,.07)}.ss--chips{align-content:center;border:1px solid #252a25;display:flex;flex-direction:row;gap:1.25rem;overflow-x:scroll;padding:1.25rem}@media screen and (min-width:75em){.ss--chips{flex-wrap:wrap;overflow:hidden}}.ss--content a:not(.ss--button):not(.ss--chip__link){color:#2a8e5a;font-weight:400}.ss--content a:not(.ss--button):not(.ss--chip__link):focus,.ss--content a:not(.ss--button):not(.ss--chip__link):hover{color:#247a4e}.ss--content>h1{margin-bottom:2.5rem}.ss--content>h1:last-child,.ss--content>p:last-child{margin-bottom:0}.ss--content ul{margin:0 0 1rem 1.25rem;padding:0}.ss--content li{font-weight:300;line-height:1.5;margin-bottom:.625rem}.ss--content--bg-gray{background-color:#eff2f2}.ss--content--bg-primary-gradient{background:linear-gradient(216.32794deg,#00bebe,#008a55)}.ss--content--text-align-left{text-align:left}.ss--content--text-align-center{text-align:center}.ss--content--text-align-right{text-align:right}.ss--content--vertically-align-center{display:flex;flex-direction:column;justify-content:center}.ss--content--width-large,.ss--content--width-medium,.ss--content--width-small{margin:0 auto}.ss--content--width-small{max-width:48rem}.ss--content--width-medium{max-width:73.125rem}.ss--content--width-large{max-width:90rem}.ss--content--gutters{padding-left:1.25rem;padding-right:1.25rem}@media screen and (min-width:75em){.ss--content--gutters{padding-left:0;padding-right:0}}.ss--content--improved-typography>h2:not(:first-child){margin-top:2.5rem}.ss--content--improved-typography>p{margin-bottom:1.5625rem}.ss--content--improved-typography>blockquote{border-left:2px solid #2a8e5a;margin-bottom:2.5rem;margin-left:0;margin-top:2.5rem;padding-bottom:.25rem;padding-left:2.5rem;padding-top:.25rem}.ss--copyright{font-size:.875rem;padding:2.5rem 0 0;text-align:center}.ss--copyright__link.ss--copyright__link{text-decoration:underline}@media screen and (min-width:75em){.ss--copyright{text-align:left}}.ss--copyright p{margin-bottom:0}.ss--cta{display:grid;overflow:hidden;position:relative;text-align:center;width:100%}@media screen and (min-width:75em){.ss--cta{padding-left:0;padding-right:0}}.ss--cta h1{font-size:2.625rem;margin-bottom:1.25rem}.ss--cta p{font-size:1.25rem;font-weight:400;margin-bottom:1.6625rem}.ss--cta__image.ss--cta__image{inset:0;-o-object-fit:cover;object-fit:cover;-o-object-position:50% 50%;object-position:50% 50%;position:absolute}.ss--cta__content{position:relative;z-index:3}.ss--cta--color-accent,.ss--cta--color-primary,.ss--cta--color-primaryGradient,.ss--cta--color-secondary{color:#fff}.ss--cta--color-primary{background-color:#2a8e5a}.ss--cta--color-secondary{background-color:#252a25}.ss--cta--color-accent{background-color:#2a8e5a}.ss--cta--color-primaryGradient{background-color:#33a49b;background-image:linear-gradient(216.32794deg,#00bebe,#008a55);background-position:50%;background-repeat:no-repeat;background-size:cover}.ss--cta--variant-hero .ss--cta__content{padding:11.25rem 1.25rem}.ss--cta--variant-default .ss--cta__content{padding:5rem 1.25rem}.ss--disclaimer p{font-size:.875rem;margin-bottom:0}.ss--drill-down{font-size:1.125rem;margin-top:4.125rem}.ss--drill-down__child,.ss--drill-down__list{list-style-type:none;margin:0;padding:0 1.25rem}.ss--drill-down__child li:not(:last-child):not(.ss--drill-down__subheading):after,.ss--drill-down__list li:not(:last-child):not(.ss--drill-down__subheading):after{background-color:#fff;content:"";display:block;height:1px;opacity:.5;width:100%}.ss--drill-down__subheading h4{padding-top:.75rem;text-transform:uppercase}.ss--drop-down{position:absolute;top:2.5rem;width:17.5rem}.ss--drop-down__list{background-color:#252a25;border-radius:0 0 .1875rem .1875rem;box-shadow:0 .375rem .375rem 0 rgba(37,42,37,.08);color:#fff;list-style:none;margin:0;padding:1.25rem}.ss--drop-down--closed{pointer-events:none}.ss--drop-down--open{position:absolute}.headroom--unpinned .ss--drop-down--open{opacity:0;pointer-events:none}.ss--title-with-icon{display:flex;gap:.625rem}.ss--title-with-icon h3{width:100%}.ss--title-with-icon svg{color:#2a8e5a;font-size:1.575rem;height:1em;margin-bottom:1rem;width:1em}.ss--figure figure{margin:0 0 1.25rem}.ss--figure figcaption{color:#7a7a7a;font-style:italic;text-align:center}.ss--footer{background-color:#252a25;color:#fff}.ss--footer a{color:#fff;font-weight:300;text-decoration:none}.ss--footer a:visited{color:inherit}.ss--footer a:hover{opacity:.8}.ss--footer svg{color:#2a8e5a;font-size:1.25rem;margin-right:.625rem}.ss--footer ul{font-size:.875rem;list-style-type:none;margin:0;padding:1.25rem 0 0}.ss--footer li:not(:last-of-type),.ss--footer li:not(:only-of-type){margin-bottom:.625rem}.ss--footer__container{margin:0 auto;max-width:73.125rem;padding:1.25rem}@media screen and (min-width:75em){.ss--footer__container{padding:1.25rem 0}}.ss--footer__wrapper{display:flex;flex-direction:column-reverse;flex-wrap:wrap;gap:2.5rem}@media print,screen and (min-width:43.75em){.ss--footer__wrapper{flex-direction:row}}@media screen and (min-width:75em){.ss--footer__wrapper{display:grid;grid-template-columns:repeat(4,1fr)}}.ss--footer__menu{padding-bottom:2.5rem}@media screen and (min-width:75em){.ss--footer__menu{padding-bottom:0}}.ss--footer__menu:first-of-type{grid-row:1/2}.ss--footer__menu:last-of-type{grid-row:2/3}.ss--footer__menu:last-of-type svg{font-size:2rem}@media screen and (min-width:75em){.ss--footer__menu:not(:first-of-type):not(:last-of-type){grid-row:1/3}}.ss--footer__menu a[aria-current]{color:#2a8e5a}.ss--footer__menu button,.ss--footer__menu form{font-size:.875rem}.ss--footer__menu form{padding-top:1.25rem}.ss--footer__menu form input{height:auto}.ss--footer__menu-heading:after{background-color:#fff;content:"";display:block;height:1px;opacity:.5;top:1.25rem;width:100%}.ss--footer__social{display:flex}.ss--form button{margin-top:.3125rem}.ss--form fieldset{border:none;margin:0;padding:0}.ss--form__statement{text-align:left}.ss--form__response{padding-bottom:1.25rem}.ss--form__reponse-body{text-align:center}.ss--grid{margin:0 auto;max-width:74.375rem}@media screen and (min-width:75em){.ss--grid{overflow:unset}}.ss--grid__wrapper{display:flex;flex-direction:column;gap:1.25rem}@media print,screen and (min-width:64em){.ss--grid__wrapper{display:grid;gap:2.5rem;grid-template-columns:repeat(2,1fr)}}.ss--grid--gutters{padding-left:1.25rem;padding-right:1.25rem}@media screen and (min-width:75em){.ss--grid--gutters{padding-left:0;padding-right:0}}.ss--grid--nested{margin:0;padding:0}.ss--grid--nested .ss--grid__wrapper{display:grid;gap:1.25rem;grid-template-columns:repeat(2,1fr)}@media print,screen and (min-width:64em){.ss--grid--nested .ss--grid__wrapper{grid-template-columns:repeat(4,1fr)}}.ss--grid--nested .ss--grid__wrapper>div>div{display:flex;justify-content:center}.ss--grid--scroll-mobile{overflow:scroll;padding:0}.ss--grid--scroll-mobile .ss--grid__wrapper{display:inline-flex;gap:1.25rem}@media screen and (min-width:75em){.ss--grid--scroll-mobile .ss--grid__wrapper>div{margin-bottom:0}}.ss--grid--col-1 .ss--grid__wrapper{display:grid;gap:1.25rem;grid-template-columns:repeat(1,1fr)}@media screen and (min-width:75em){.ss--grid--col-3 .ss--grid__wrapper{display:grid;gap:1.25rem;grid-template-columns:repeat(3,1fr)}}@media screen and (min-width:31.25em){.ss--grid--col-4 .ss--grid__wrapper{display:grid;grid-template-columns:repeat(2,1fr)}}@media screen and (min-width:50em){.ss--grid--col-4 .ss--grid__wrapper{display:grid;grid-template-columns:repeat(3,1fr)}}@media print,screen and (min-width:64em){.ss--grid--col-4 .ss--grid__wrapper{display:grid;gap:1.25rem;grid-template-columns:repeat(4,1fr)}}.ss--grid--gap-large .ss--grid__wrapper{gap:2.5rem}@media print,screen and (max-width:74.99875em){.ss--grid--gap-none-mobile .ss--grid__wrapper{gap:0}.ss--grid--gap-none-mobile .ss--grid__wrapper>div{margin:0}.ss--grid--gap-none-mobile .ss--grid__wrapper ul{margin-bottom:0}}.ss--grid--reverse .ss--grid__wrapper{flex-direction:column-reverse}.ss--grid--justify-center{justify-content:center}.ss--header{background-color:#252a25;box-shadow:0 .1875rem .375rem 0 rgba(37,42,37,.08),0 .1875rem .375rem 0 rgba(37,42,37,.08);position:relative;transition:background-color .3s linear;z-index:10}.layout--transparent-header .ss--header{background-color:transparent;background-image:linear-gradient(180deg,rgba(37,42,37,.4),transparent);box-shadow:none;position:relative}.layout--transparent-header .headroom--pinned .ss--header{background-color:#252a25;box-shadow:0 .1875rem .375rem 0 rgba(37,42,37,.08),0 .1875rem .375rem 0 rgba(37,42,37,.08)}.ss--header__container{margin:0 auto;max-width:73.125rem}.ss--header__wrapper{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-end;padding:.625rem 1.25rem;position:relative}@media screen and (min-width:75em){.ss--header__wrapper{padding:.625rem 0 1.25rem}}.ss--header__top .ss--header__wrapper{font-size:.875rem;padding:.41667rem 0;text-transform:uppercase}.ss--header__logo{justify-self:flex-start;margin-right:auto;position:relative;z-index:2}@media screen and (min-width:75em){.ss--header__logo{transform:translateY(-.375rem) scale(1.35);transform-origin:0 100%}}.ss--header__menu{display:none}@media screen and (min-width:75em){.ss--header__menu{display:block;margin-right:0}}.ss--header__cta{display:none}@media screen and (min-width:22.5em){.ss--header__cta{display:flex}}@media screen and (min-width:75em){.ss--header__cta{margin-left:1em}}.ss--header__cta>*{margin:0}.ss--header__icon button,.ss--header__icon span{display:flex}.ss--header__icon button{cursor:pointer}.ss--header__icon rect{fill:#fff}@media screen and (min-width:75em){.ss--header__icon{display:none}}.ss--header__top{background:linear-gradient(90deg,#252a25,#1e221e);color:#fff;display:none;font-family:Monda,sans-serif}@media screen and (min-width:75em){.ss--header__top{display:block}}.ss--header__link{color:#fff;transition:color .25s ease,opacity .25s ease}.ss--header__link:focus,.ss--header__link:hover{opacity:.65}.ss--header__link:not(:first-child){margin-left:1.25rem}.ss--header__link--parent{color:#2a8e5a}.ss--header__phone{justify-self:start;margin-left:0;margin-right:auto}.ss--hero{background-color:#33a49b;background-image:url("https://d33wubrfki0l68.cloudfront.net/ba9946ed33a410dafa38f5738b4e5f7ed4856e4d/7f519/hero-bg.webp");background-position:50%;background-repeat:no-repeat;background-size:cover;color:#fff;padding:11.25rem 0}.ss--hero p{font-size:1.25rem;font-weight:400}.ss--icon{align-items:center;display:flex;justify-content:center}.ss--image{margin:auto;position:relative;width:100%}.image-with-content .ss--image{align-content:center}.ss--image img{margin-bottom:0}.ss--image__image{background-color:#f1f3f4;border-radius:6px;overflow:hidden}.ss--image__logo:not(img){bottom:1.25rem;left:1.25rem;position:absolute}.ss--image__icon{background:transparent;border:0;bottom:1.25rem;color:#fff;filter:drop-shadow(1px 1px 4px rgba(37,42,37,.5));opacity:0;position:absolute;right:1.25rem;transform:translate(100%,100%);transition:all .25s cubic-bezier(.17,.67,.37,.95)}:hover>.ss--image__icon{opacity:1;transform:translate(0)}.ss--image--width-small{max-width:48rem}.ss--image--width-medium{max-width:73.125rem}.ss--image--width-large{max-width:90rem}.ss--image--width-full{max-width:unset}.ss--image--width-full .ss--image__wrap>div{border-radius:0}.ss--image--elevated .ss--image__image{box-shadow:0 2.8px 2.2px rgba(0,0,0,.02),0 6.7px 5.3px rgba(0,0,0,.028),0 12.5px 10px rgba(0,0,0,.035),0 22.3px 17.9px rgba(0,0,0,.042),0 41.8px 33.4px rgba(0,0,0,.05),0 100px 80px rgba(0,0,0,.07)}.ss--image--lightbox{position:relative}.ss--image--lightbox>div{cursor:zoom-in}.ss--image-list{display:grid;gap:16px 16px;grid-auto-rows:125px;grid-template-areas:". . . ."}.ss--image-list>*{border-radius:3px}.ss--image-with-content{display:flex;flex-direction:column-reverse;gap:1.25rem;margin:0 auto;max-width:73.125rem}@media print,screen and (min-width:64em){.ss--image-with-content{display:grid;gap:2.5rem;grid-template-columns:repeat(2,1fr)}}.ss--image-with-content--gutters{padding-left:1.25rem;padding-right:1.25rem}@media screen and (min-width:75em){.ss--image-with-content--gutters{padding-left:0;padding-right:0}}.ss--image-with-content--image-left>div{grid-row:1/2}.ss--image-with-content--image-left>div:first-of-type{grid-column:2/3}.ss--image-with-content--image-left>div:last-of-type{grid-column:1/2}.ss--input{padding-bottom:1.25rem}.ss--input input{-webkit-appearance:none;appearance:none;border:1px solid #252a25;border-radius:3px;box-sizing:border-box;display:block;height:2.8125rem;margin-top:.3125rem;padding:.75em 1em;width:100%}.ss--input input:-ms-input-placeholder{opacity:.4}.ss--input input::placeholder{opacity:.4}.ss--input label{clip:rect(0,0,0,0)!important;border:0!important;height:1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:1px!important}.ss--lazy-iframe{background-color:#252a25;padding-top:56.25%;position:relative}.ss--lazy-iframe,.ss--lazy-iframe iframe{border-radius:6px;overflow:hidden;width:100%}.ss--lazy-iframe iframe{height:100%;left:0;position:absolute;top:0}.ss--lazy-iframe--elevated{box-shadow:0 2.8px 2.2px rgba(0,0,0,.02),0 6.7px 5.3px rgba(0,0,0,.028),0 12.5px 10px rgba(0,0,0,.035),0 22.3px 17.9px rgba(0,0,0,.042),0 41.8px 33.4px rgba(0,0,0,.05),0 100px 80px rgba(0,0,0,.07)}.ss--logo{align-items:center;color:#fff;display:flex}.ss--logo svg{height:2.5rem}@media screen and (min-width:75em){.ss--logo svg{height:3.4375rem}}.layout--transparent-header .headroom--unfixed .ss--logo path{fill:#fff}.ss--menu__list{display:flex;list-style:none;margin:0;padding:0}.ss--menu__list .ss--menu__item,.ss--menu__list span{display:flex}.ss--menu__list .ss--menu__item{padding:0}.ss--menu__toggle{background:none;border:0;color:inherit;padding:0}.ss--menu__item{display:inline-block;margin:0;padding:.5em 0}.ss--menu__item--button{background-color:#2a8e5a;border-radius:3px;box-shadow:0 .2px 2.2px rgba(0,0,0,.02),0 .4px 5.3px rgba(0,0,0,.028),0 .8px 10px rgba(0,0,0,.035),0 1.3px 17.9px rgba(0,0,0,.042),0 2.5px 33.4px rgba(0,0,0,.05),0 6px 80px rgba(0,0,0,.07);cursor:pointer;margin-left:1em;position:relative;transition:background .25s ease,opacity .25s ease;z-index:6}.ss--menu__item--button:focus,.ss--menu__item--button:hover{background:#247a4e}.ss--menu__item--button:active{background:#216f46}.ss--menu__item--button .ss--menu__link{font-size:1.125rem;line-height:normal;padding:.6em 1.5em}.ss--menu__item--button .ss--menu__link:focus,.ss--menu__item--button .ss--menu__link:hover{opacity:1}.ss--menu__item--button .ss--menu__link--parent{color:#fff}.ss--menu__link{align-items:center;color:#fff;display:flex;font-size:1rem;font-weight:700;letter-spacing:.09375rem;line-height:1;padding:.5em 1em;position:relative;text-decoration:none;z-index:2}.ss--menu__link:focus,.ss--menu__link:hover{opacity:.8}@media screen and (min-width:87.5em){.ss--menu__link{font-size:1.125rem}}.ss--menu__link>svg{font-size:1rem;height:1em;margin-left:.125rem;width:1em}.ss--menu__link--parent{color:#2a8e5a}.ss--menu-icon{align-items:center;background:none;border:0;display:flex;font-size:3.125rem;overflow:visible;padding:0}.ss--menu-icon svg{font-size:var(--header-button-size);height:1em;width:1em}.ss--menu-item{display:block;margin:0;position:relative}.ss--menu-item__back,.ss--menu-item__icon{height:1em}.ss--menu-item__back{margin-right:.5rem}.ss--menu-item a,.ss--menu-item button{padding:.5rem 0}.ss--menu-item--is-mobile a,.ss--menu-item--is-mobile button{font-weight:600;padding:.75rem 0}.ss--menu-item--is-mobile a>span,.ss--menu-item--is-mobile button>span{align-items:center;display:flex;justify-content:space-between}.ss--menu-item--is-mobile a>span>span,.ss--menu-item--is-mobile button>span>span{align-items:center;display:flex}.ss--menu-item--is-mobile a>span svg,.ss--menu-item--is-mobile button>span svg{font-size:2rem}.ss--menu-item--is-back a>span,.ss--menu-item--is-back button>span{justify-content:normal;margin-left:-.42857rem}.ss--menu-item--is-back a>span>span,.ss--menu-item--is-back button>span>span{line-height:1;margin-left:.375rem}.ss--menu-item--is-back .ss--menu-item--current{--button-bg-color:#fff}.ss--menu-item--current{--button-bg-color:#2a8e5a}.ss--pagination{align-items:center;display:flex;justify-content:space-between;margin:0 auto;max-width:73.125rem;padding:0 1.25rem}@media screen and (min-width:75em){.ss--pagination{justify-content:normal;padding:0}}.ss--pagination__next,.ss--pagination__previous{align-items:center;display:flex}.ss--pagination a{color:#252a25}.ss--pagination a:not(:first-of-type):not(:last-of-type){padding:0 1.25rem}.ss--pagination a:first-of-type{padding:0 1.25rem 0 0}.ss--pagination a:last-of-type{padding:0 0 0 1.25rem}.ss--pagination a>svg{font-size:1.5rem;height:1em;width:1em}.ss--pagination a[aria-current]{color:#2a8e5a}.ss--post-card{background-color:#fff;border-radius:6px;display:flex;flex-direction:column;overflow:hidden}.ss--post-card__image-frame{position:relative}.ss--post-card__logo{bottom:1.25rem;left:1.25rem;position:absolute}.ss--post-card__content{padding:1.25rem}.ss--post-card__tags{font-weight:300;margin-bottom:2rem}.ss--post-card__tags>a{font-weight:300}.ss--post-card__meta{font-weight:600;margin-bottom:.5rem}.ss--post-card__excerpt{flex-grow:1}.ss--post-card__title{color:#252a25}.ss--post-card--elevated{box-shadow:0 2.8px 2.2px rgba(0,0,0,.02),0 6.7px 5.3px rgba(0,0,0,.028),0 12.5px 10px rgba(0,0,0,.035),0 22.3px 17.9px rgba(0,0,0,.042),0 41.8px 33.4px rgba(0,0,0,.05),0 100px 80px rgba(0,0,0,.07)}.ss--post-intro__date,.ss--post-intro__tags,.ss--post-intro__tags>a{font-weight:300}.ss--post-intro__meta dt{clip:rect(0,0,0,0)!important;border:0!important;height:1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:1px!important}.ss--post-intro__meta dd,.ss--post-intro__meta dl{display:inline-block}.ss--post-intro__meta dd{font-weight:600;margin:0}.ss--post-intro__meta dl:not(:first-child):before{color:#2a8e5a;content:"·";display:inline-block;margin:0 .5em}.ss--post-intro__tag{border:1px solid #2a8e5a;border-radius:1em;font-size:.875rem;line-height:1;padding:.25em 1em}.ss--slider{margin:0 auto;max-width:49.25rem}.ss--slider input[type=range]{-moz-appearance:none;-webkit-appearance:none;background:#f1f3f4;border-radius:3px;height:6px;margin:.9375rem 0;outline:none;width:100%}.ss--slider input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;background:linear-gradient(216.32794deg,#00bebe,#008a55);border-radius:50em;box-shadow:0 .1875rem .375rem 0 rgba(37,42,37,.08),0 .1875rem .375rem 0 rgba(37,42,37,.08);cursor:pointer;height:1rem;width:1rem}.ss--slider input[type=range]::-moz-range-thumb{-webkit-appearance:none;background:linear-gradient(216.32794deg,#00bebe,#008a55);border-radius:50em;box-shadow:0 .1875rem .375rem 0 rgba(37,42,37,.08),0 .1875rem .375rem 0 rgba(37,42,37,.08);cursor:pointer;height:1rem;width:1rem}.ss--slider input[type=range]::-ms-thumb{-webkit-appearance:none;background:linear-gradient(216.32794deg,#00bebe,#008a55);border-radius:50em;box-shadow:0 .1875rem .375rem 0 rgba(37,42,37,.08),0 .1875rem .375rem 0 rgba(37,42,37,.08);cursor:pointer;height:1rem;margin-top:0;width:1rem}.ss--slider__number{margin:0 auto;max-width:20%}.ss--slider__number input{-webkit-appearance:none;appearance:none;border:1px solid #252a25;border-radius:3px;box-sizing:border-box;display:block;height:2.8125rem;margin-top:.3125rem;padding:.75em 1em;width:100%}.ss--slider__number input:-ms-input-placeholder{opacity:.4}.ss--slider__number input::placeholder{opacity:.4}.ss--slider__price{padding-top:1.25rem}.ss--slider label{clip:rect(0,0,0,0)!important;border:0!important;height:1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:1px!important}.ss--share{color:#2a8e5a}.ss--share svg{font-size:2.1875rem;height:1em;width:1em}.ss--share svg:focus,.ss--share svg:hover{color:#247a4e}.ss--share button{align-items:center}.ss--share button:first-child:nth-last-child(n+4),.ss--share button:first-child:nth-last-child(n+4)~button{margin-top:1.25rem}.ss--share button:not(:last-child){margin-right:1.25rem}.ss--share__icons,.ss--share button{display:flex;flex-direction:row}.ss--share__icons{margin:auto 0}.ss--share__heading{color:#252a25;font-size:1.575rem;line-height:1.4;margin:0 0 .625rem}.ss--spacer{padding:1.25rem 0;position:relative}.ss--spacer--padding-double{padding:2.5rem 0}.ss--table{align-content:center;display:flex;margin:0;max-width:calc(100vw - 2.5rem);overflow-x:scroll;table-layout:fixed;text-align:left}@media screen and (min-width:75em){.ss--table{overflow:hidden}}.ss--table__good{fill:#2a8e5a}.ss--table__bad{fill:#d85d5d}.ss--table__na{fill:#7a7a7a;opacity:.5}.ss--table table{border-collapse:collapse;margin:auto;width:100%}.ss--table thead{font-family:Monda,Arial,sans-serif;font-size:1.5rem;text-align:center}.ss--table thead th{border-bottom:2px solid #7a7a7a;font-weight:400;text-align:center}.ss--table td,.ss--table th{border-bottom:1px solid #f1f3f4;min-width:10rem;padding:1rem}@media print,screen and (min-width:64em){.ss--table td,.ss--table th{max-width:100%;min-width:2rem;white-space:normal}}.ss--table tbody{margin:0 1rem}.ss--table tbody tr{border-bottom:1px solid #7a7a7a}.ss--table tbody tr:last-of-type{border-bottom:unset}.ss--table tbody tr th:first-child{font-weight:600;text-align:left}@media print,screen and (min-width:64em){.ss--table tbody tr th:first-child{font-size:1.5rem}}.ss--table tbody tr td{text-align:center}.ss--table tfoot td{border-bottom:0}.ss--table__wrapper{margin:0 auto 1.25rem;max-width:90rem;padding:0;width:100%}.ss--table--widthsmall .ss--table__wrapper{max-width:48rem}.ss--table--width-medium .ss--table__wrapper{max-width:73.125rem}.ss--table--width-large .ss--table__wrapper{max-width:90rem}.ss--table--gutters{margin:auto;max-width:calc(100vw - 2.5rem)}.ss--table--bordered{border:2px solid;border-radius:3px}.ss--table--bordered .ss--table__wrapper{margin-bottom:0}.ss--testimonial{text-align:center}.ss--testimonial blockquote{margin:0 0 1.25rem}@media screen and (min-width:75em){.ss--testimonial blockquote{margin-bottom:1.25rem;margin-left:initial;margin-right:initial;margin-top:initial}}.ss--testimonial__citation cite{color:#252a25}.ss--testimonial__author{margin-bottom:.41667rem}.ss--testimonial__author,.ss--testimonial__company,.ss--testimonial__role{display:block}.ss--testimonial__company,.ss--testimonial__role{font-weight:400}.ss--testimonial__cite{margin-bottom:1.25rem}.ss--testimonial__image{margin:0 auto 1.25rem;width:6.25rem}.ss--testimonial__image img{border-radius:50em}.ss--textarea{padding-bottom:1.25rem}.ss--textarea textarea{-webkit-appearance:none;border:1px solid #252a25;border-radius:3px;box-sizing:border-box;display:block;margin-top:.3125rem;max-width:100%;min-height:11.25rem;min-width:100%;padding:.75em 1em}.ss--textarea textarea:-ms-input-placeholder{opacity:.4}.ss--textarea textarea::placeholder{opacity:.4}.ss--textarea label{clip:rect(0,0,0,0)!important;border:0!important;height:1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:1px!important}.ss--video{display:flex;flex-direction:column;justify-content:center;position:relative}.ss--video>div{height:0!important;overflow:hidden;padding-bottom:56.25%;padding-top:35px;position:relative;width:unset!important}.ss--video iframe{border-radius:6px;height:100%;left:0;position:absolute;top:0;width:100%}.ss--video--elevated>div{box-shadow:0 2.8px 2.2px rgba(0,0,0,.02),0 6.7px 5.3px rgba(0,0,0,.028),0 12.5px 10px rgba(0,0,0,.035),0 22.3px 17.9px rgba(0,0,0,.042),0 41.8px 33.4px rgba(0,0,0,.05),0 100px 80px rgba(0,0,0,.07)}.ss--video-with-content{display:flex;flex-direction:column-reverse;gap:1.25rem;margin:0 auto;max-width:73.125rem}@media print,screen and (min-width:64em){.ss--video-with-content{display:grid;gap:2.5rem;grid-template-columns:repeat(2,1fr)}}.ss--video-with-content--gutters{padding-left:1.25rem;padding-right:1.25rem}@media screen and (min-width:75em){.ss--video-with-content--gutters{padding-left:0;padding-right:0}}.ss--video-with-content--video-left>div{grid-row:1/2}.ss--video-with-content--video-left>div:first-of-type{grid-column:2/3}.ss--video-with-content--video-left>div:last-of-type{grid-column:1/2}.ss--licenses-item{display:flex;flex-direction:column;height:100%;justify-content:space-between;padding:2.5rem;text-align:center}.ss--licenses-item a:not(.ss--button){color:currentColor;text-decoration:underline}.ss--licenses-item__heading{background-color:#f1f3f4;border-radius:3rem;color:#252a25;font-size:1rem;font-weight:400;margin:0 auto 1.5rem;max-width:12.5rem;padding:.625rem}.ss--licenses-item__price{font-size:3.25rem}.ss--licenses-item__badge{color:#00bfbe;font-family:Monda,Arial,sans-serif;font-size:.875em;font-weight:600;padding:.25em .5em;position:absolute;text-transform:uppercase;transform:translateX(-2rem) rotate(20deg)}.ss--licenses-item__description{font-size:1.125rem}.ss--licenses-item__features{font-size:1.125rem;list-style:none;margin:0;opacity:.64;padding:0}.ss--licenses-item__features li{margin-bottom:1rem}.ss--licenses-item__action{min-height:5.75rem}.ss--licenses-item__note{margin-top:.5rem}.ss--licenses-item--primary .ss--licenses-item__heading{background-color:#00bfbe;color:#fff}.ss--licenses-item--secondary .ss--licenses-item__heading{background-color:#252a25;color:#fff}.ss--licenses-item--free .ss--licenses-item__hero{padding-bottom:4rem}.ss--licenses-item--masked .ss--licenses-item__price{display:block;font-size:2rem;padding-bottom:1.25rem}.ss--licenses{grid-gap:1.25rem;display:grid;grid-template-columns:1fr;grid-template-rows:1fr;margin:0 auto;max-width:74.375rem}@media print,screen and (min-width:64em){.ss--licenses{grid-template-columns:1fr 2fr}}.ss--licenses a:not(.ss--button){color:currentColor;text-decoration:underline}.ss--licenses__item-heading{background-color:#00bfbe;border-radius:3rem;color:#fff;font-size:1rem;font-weight:400;margin:0 auto 1.5rem;max-width:12.5rem;padding:.625rem}.ss--licenses__item-description{font-size:1.125rem}.ss--licenses__item-features{font-size:1.125rem;list-style:none;opacity:.64;padding:0}.ss--licenses__item-features li{margin-bottom:1rem}.ss--licenses__item-note{margin-top:.5rem}.ss--licenses__paid{grid-gap:1.25rem;border-radius:6px;display:grid;grid-template-columns:1fr;grid-template-rows:1fr}@media print,screen and (min-width:43.75em){.ss--licenses__paid{grid-template-columns:1fr 1fr}}.ss--surface{border-radius:6px;height:100%}.ss--surface,.ss--surface--primary{background-image:linear-gradient(216.32794deg,#00bebe,#008a55)}.ss--surface--primary{color:#fff}.ss--surface--secondary{background:#252a25;color:#fff}.ss--surface--white{background:#fff}.ss--surface--default,.ss--surface--white{border:2px solid #252a25;box-shadow:inset 0 1px 63px 0 rgba(0,0,0,.05)}.ss--surface--default{background:#f1f3f4}.ss--surface--none{background:transparent;box-shadow:inset 0 1px 63px 0 rgba(0,0,0,.05)}.ss--surface--pattern{position:relative}.ss--surface--pattern:before{background:url("https://d33wubrfki0l68.cloudfront.net/44ac09e65d0ffb2ad8bd72ddd575ed5b476e0224/ce639/bg-pattern.svg") repeat-y 125% 50%;background-size:415px 580px;content:" ";display:block;inset:0;pointer-events:none;position:absolute}@media print,screen and (min-width:43.75em){.ss--surface--small-only{background:unset;border:unset;box-shadow:unset}}@media screen and (max-width:43.74875em){.ss--surface--medium-up{background:unset;border:unset;box-shadow:unset}}.ss--surface--elevated{box-shadow:0 2.8px 2.2px rgba(0,0,0,.02),0 6.7px 5.3px rgba(0,0,0,.028),0 12.5px 10px rgba(0,0,0,.035),0 22.3px 17.9px rgba(0,0,0,.042),0 41.8px 33.4px rgba(0,0,0,.05),0 100px 80px rgba(0,0,0,.07)}.ss--card{text-align:center}.ss--card__content{padding:2.5rem}.ss--profile{color:#252a25;font-size:1rem;margin:1.25rem auto}.ss--profile__wrapper{align-items:stretch;display:flex;flex-direction:column}@media print,screen and (min-width:43.75em){.ss--profile__wrapper{flex-direction:row}}.ss--profile__images{align-items:center;display:flex;justify-content:flex-start;margin-bottom:.625rem;position:relative}@media print,screen and (min-width:43.75em){.ss--profile__images{align-items:center;flex-direction:row;min-width:10rem;padding-left:0}}.ss--profile__greeting{font-style:italic}.ss--profile__image,.ss--profile__logo{border-radius:50%;overflow:hidden}.ss--profile__image{margin:0;position:relative}.ss--profile__logo:nth-child(2){margin-left:.625rem}@media print,screen and (min-width:43.75em){.ss--profile__content{padding:0 1.25rem;text-align:left}}.ss--profile__content p:last-child{margin-bottom:0}.ss--profile__name,.ss--profile__role{margin-bottom:.25em}.ss--profile__role{line-height:1.2}.ss--profile__bio{font-size:.875rem}.ss--profile--staff{background-color:#f1f3f4;border:2px solid #252a25;border-radius:6px;height:calc(100% - 2.5rem);height:100%;margin-bottom:0;margin-top:0;overflow:hidden;position:relative;text-align:center;width:100%}.ss--profile--staff .ss--profile__wrapper{align-items:flex-start;flex-direction:column;height:17.1875rem}.ss--profile--staff .ss--profile__images{margin-bottom:0;position:relative;width:100%}.ss--profile--staff .ss--profile__images:after{background:linear-gradient(216.32794deg,#00bebe,#008a55);bottom:50%;content:"";display:block;left:0;right:0;top:0}.ss--profile--staff .ss--profile__image{margin:1.25rem auto 0;max-width:10rem}.ss--profile--staff .ss--profile__content{padding:1.25rem;text-align:inherit;width:100%}.ss--profile--staff .ss--profile__logo{bottom:0;left:50%;opacity:.5;position:absolute;width:4rem}.ss--profile--staff .ss--profile__name{font-size:1.25rem;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ss--profile--staff .ss--profile__bio{height:17.1875rem;left:0;opacity:0;overflow:scroll;padding:.625rem;position:absolute;right:0;top:100%}.ss--document-cta__title,h2,h3{line-height:1.25;margin-bottom:1.25rem}.ss--document-cta__title,h2{font-size:2rem}.ss--document-cta{margin:0 auto;max-width:74.375rem;overflow:hidden}@media print,screen and (min-width:64em){.ss--document-cta{padding-top:4rem}}.ss--document-cta__wrapper{grid-column-gap:1.25rem;display:grid;grid-template-columns:1fr;grid-template-rows:1fr;padding:2.5rem}@media print,screen and (min-width:64em){.ss--document-cta__wrapper{grid-template-columns:3.5fr 3fr}}.ss--document-cta__cover{display:none;position:relative}@media print,screen and (min-width:64em){.ss--document-cta__cover{display:block}}.ss--document-cta__cover:after{background:#252a25;bottom:calc(-2.5rem - 1px);content:"";display:block;height:1px;position:absolute;width:100%;z-index:10}.ss--document-cta__content{padding-bottom:1.25rem}.ss--document-cta__paper{background:#fff;border:1px solid #252a25;border-radius:3px;box-shadow:calc(2rem - 1px) calc(2rem + 1px) 0 0 #f5f5f5,2rem 2rem 0 0 #252a25,2rem 2.1875rem .375rem 0 rgba(37,42,37,.12),2rem 2.1875rem 2.375rem 0 rgba(37,42,37,.12);left:2rem;padding:1.25rem;position:absolute;right:2rem;top:-6rem;transition:transform .25s ease;z-index:10}:hover>div>.ss--document-cta__paper{transform:translateY(-.25rem)}.ss--document-cta__body{font-size:1.25rem}.ss--document-cta__cover-title{position:relative}.ss--document-cta__cover-title h3{margin-bottom:0}.ss--swatch{text-align:center}.ss--swatch__content{padding:1.25rem}.ss--swatch__sample{aspect-ratio:1/1}.ss--staff{font-size:1rem}.ss--staff__wrapper{margin:0 auto;max-width:74.375rem;padding:0 1.25rem}.ss--staff__list{align-items:stretch;display:flex;flex-wrap:wrap;justify-content:center}.ss--staff__item{margin:0 .625rem 1.25rem;max-width:17.1875rem;min-width:16.25rem;width:100%}.ss--staff--center{text-align:center}.ss--notification{align-items:center;display:flex;flex-direction:row;justify-content:space-around;position:relative}.ss--notification a,.ss--notification button{color:currentColor;transition:opacity .2s linear}.ss--notification a:active,.ss--notification a:focus,.ss--notification a:hover,.ss--notification button:active,.ss--notification button:focus,.ss--notification button:hover{opacity:.8}.ss--notification button{background:transparent;border:0;bottom:0;cursor:pointer;left:0;padding:.625rem;position:absolute;top:0}.ss--notification__content{align-items:center;display:flex;flex-direction:row;font-weight:700;margin:auto;padding:.625rem 2.5rem;text-align:center}.ss--notification__title{font-family:Monda,Arial,sans-serif;line-height:1}.ss--notification__button{display:inline-flex}.ss--notification__cta{font-family:Monda,Arial,sans-serif;line-height:1;margin-left:.5rem}.ss--notification__icon{height:1rem;margin-left:.5rem;width:1rem}.ss--notification--default{background-color:#fff;color:#252a25}.ss--notification--default .ss--notification__cta,.ss--notification--default .ss--notification__icon{color:#2a8e5a}.ss--notification--accent{background:#00bfbe;color:#fff}.ss--notification--gradient{background:linear-gradient(216.32794deg,#00bebe,#008a55);color:#fff}.ss--notification--primary{background-color:#2a8e5a;color:#fff}.ss--notification--alert{background-color:#d85d5d;color:#fff}.ss--notification--warning{background-color:#d8b85d;color:#fff}*{box-sizing:border-box}body{margin:0;overflow-x:hidden}main{display:block}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}form{margin:0}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}:root{--primary-color:#2a8e5a}:export{primaryColor:#2a8e5a;secondaryColor:#252a25;accentColor:#00bfbe;errorColor:#d85d5d;warningColor:#d8b85d;black:#252a25;white:#fff;lightGray:#f1f3f4;darkGray:#7a7a7a;primaryGradient:linear-gradient(216.32794deg,#00bebe,#008a55);mediumBreakpoint:700px;xlargeBreakpoint:1200px;xxlargeBreakpoint:1400px}body{color:#252a25;font-family:IBM Plex Sans,Arial,sans-serif}h1,h2,h3,h4,h5,h6{font-family:Monda,Arial,sans-serif;font-weight:700}h1,h2,h3,h4,h5,h6,p{margin-top:0}h1{font-size:2.625rem;line-height:1.4;margin-bottom:1.6625rem}h2,h3{line-height:1.25;margin-bottom:1.25rem}h2{font-size:2rem}h3{font-size:1.575rem;line-height:1.4}h4{font-size:1rem;letter-spacing:.065em;line-height:1.66rem}a{text-decoration:none}blockquote,cite,p{line-height:1.5}blockquote{font-size:1.3125rem;font-style:italic;font-weight:400;margin-top:0}blockquote>p:before{content:"“"}blockquote>p:after{content:"”"}blockquote>footer,cite{font-size:1.125rem;font-style:normal;font-weight:600}figcaption{font-size:.875rem;margin-bottom:1rem}figcaption,label,p{font-weight:300}ol{margin:0;padding:0 0 0 1rem}pre{padding:1.25rem}p code,pre{background:#f1f3f4;font-size:.875rem;margin-top:0;overflow:scroll}p code{padding:.625rem 1.25rem}abbr[title]{text-decoration:none}hr{margin-bottom:2.5rem;margin-top:2.5rem;min-width:4rem}strong{font-weight:600}:root{--layout-sidebar-bg:rgba(37,42,37,.9)}.layout__sidebar{-webkit-font-smoothing:antialiased;background-color:var(--layout-sidebar-bg);z-index:15}.layout__sidebar,.modal{bottom:0;color:#fff;left:0;position:fixed;right:0;top:0}.modal__loading{inset:0;margin:auto;position:absolute;z-index:-1}.modal__error{background-color:red;border-radius:.5rem;bottom:auto;display:inline-block;inset:0;margin:6rem auto auto;max-width:25rem;padding:1rem;position:absolute;text-align:center}.modal__error p:last-child{margin-bottom:0}.modal__close{align-items:center;background:none;border:0;color:currentColor;display:flex;position:absolute;right:1rem;top:1rem}.headroom{left:0;right:0;top:0;will-change:transform;z-index:20}.headroom-wrapper--sidebar .headroom{position:fixed;transform:translateY(-100%)}.headroom--unfixed{position:relative;transform:none}.layout--transparent-header .headroom--unfixed{position:absolute}.headroom--scrolled{transition:transform .2s ease-in-out,background-color 1ms linear}.headroom--unpinned{position:fixed;transform:translate3d(0,-100%,0)}.headroom--pinned{position:fixed;transform:translateZ(0)}.layout--transparent-header .headroom-wrapper{left:0;position:absolute;right:0;top:0}</style><meta name="generator" content="Gatsby 3.14.5" /><style data-emotion="css-global mn9w2k">html{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;box-sizing:border-box;-webkit-text-size-adjust:100%;}*,*::before,*::after{box-sizing:inherit;}strong,b{font-weight:700;}body{margin:0;color:rgba(0, 0, 0, 0.87);font-family:IBM Plex Sans,sans-serif;font-weight:400;font-size:1rem;line-height:1.5;background-color:#fff;}@media print{body{background-color:#fff;}}body::backdrop{background-color:#fff;}</style><style data-emotion="css "></style><title data-react-helmet>BPFDoor - An Evasive Linux Backdoor Technical Analysis</title><link data-react-helmet rel="apple-touch-icon" sizes="57x57" href="https://www.datocms-assets.com/56687/1634009075-icon.svg?w=57&amp;h=57" /><link data-react-helmet rel="apple-touch-icon" sizes="60x60" href="https://www.datocms-assets.com/56687/1634009075-icon.svg?w=60&amp;h=60" /><link data-react-helmet rel="apple-touch-icon" sizes="72x72" href="https://www.datocms-assets.com/56687/1634009075-icon.svg?w=72&amp;h=72" /><link data-react-helmet rel="apple-touch-icon" sizes="76x76" href="https://www.datocms-assets.com/56687/1634009075-icon.svg?w=76&amp;h=76" /><link data-react-helmet rel="apple-touch-icon" sizes="114x114" href="https://www.datocms-assets.com/56687/1634009075-icon.svg?w=114&amp;h=114" /><link data-react-helmet rel="apple-touch-icon" sizes="120x120" href="https://www.datocms-assets.com/56687/1634009075-icon.svg?w=120&amp;h=120" /><link data-react-helmet rel="apple-touch-icon" sizes="144x144" href="https://www.datocms-assets.com/56687/1634009075-icon.svg?w=144&amp;h=144" /><link data-react-helmet rel="apple-touch-icon" sizes="152x152" href="https://www.datocms-assets.com/56687/1634009075-icon.svg?w=152&amp;h=152" /><link data-react-helmet rel="apple-touch-icon" sizes="180x180" href="https://www.datocms-assets.com/56687/1634009075-icon.svg?w=180&amp;h=180" /><link data-react-helmet rel="icon" sizes="16x16" href="https://www.datocms-assets.com/56687/1634009075-icon.svg?w=16&amp;h=16" type="image/svg" /><link data-react-helmet rel="icon" sizes="32x32" href="https://www.datocms-assets.com/56687/1634009075-icon.svg?w=32&amp;h=32" type="image/svg" /><link data-react-helmet rel="icon" sizes="96x96" href="https://www.datocms-assets.com/56687/1634009075-icon.svg?w=96&amp;h=96" type="image/svg" /><link data-react-helmet rel="icon" sizes="192x192" href="https://www.datocms-assets.com/56687/1634009075-icon.svg?w=192&amp;h=192" type="image/svg" /><link data-react-helmet rel="alternate" type="application/rss+xml" title="RSS Feed for sandflysecurity.com" href="/blog/rss.xml" /><meta data-react-helmet name="viewport" content="initial-scale=1, width=device-width" /><meta data-react-helmet name="msapplication-square70x70" content="https://www.datocms-assets.com/56687/1634009075-icon.svg?w=70&amp;h=70" /><meta data-react-helmet name="msapplication-square150x150" content="https://www.datocms-assets.com/56687/1634009075-icon.svg?w=150&amp;h=150" /><meta data-react-helmet name="msapplication-square310x310" content="https://www.datocms-assets.com/56687/1634009075-icon.svg?w=310&amp;h=310" /><meta data-react-helmet name="msapplication-square310x150" content="https://www.datocms-assets.com/56687/1634009075-icon.svg?w=310&amp;h=150" /><meta data-react-helmet name="application-name" content="Sandfly Security" /><meta data-react-helmet name="format-detection" content="telephone=no" /><meta data-react-helmet property="og:title" content="BPFDoor - An Evasive Linux Backdoor Technical Analysis" /><meta data-react-helmet name="twitter:title" content="BPFDoor - An Evasive Linux Backdoor Technical Analysis" /><meta data-react-helmet name="description" content="BPFDoor is an stealthy Linux backdoor operating for years undetected. We disclose full technical details and detection techniques here." /><meta data-react-helmet property="og:description" content="BPFDoor is an stealthy Linux backdoor operating for years undetected. We disclose full technical details and detection techniques here." /><meta data-react-helmet name="twitter:description" content="BPFDoor is an stealthy Linux backdoor operating for years undetected. We disclose full technical details and detection techniques here." /><meta data-react-helmet name="twitter:site" content="@https://twitter.com/sandflysecurity" /><meta data-react-helmet name="twitter:card" content="summary" /><meta data-react-helmet property="article:modified_time" content="2022-05-12T11:41:08Z" /><meta data-react-helmet property="article:published_time" content="2022-05-11T09:08:42Z" /><meta data-react-helmet property="og:locale" content="en_EN" /><meta data-react-helmet property="og:type" content="article" /><meta data-react-helmet property="og:site_name" content="Sandfly Security" /><meta data-react-helmet property="og:image" content="https://www.datocms-assets.com/56687/1652242695-bpfdoor-deleted-binary.png?w=1000&amp;fit=max&amp;fm=jpg" /><meta data-react-helmet name="twitter:image" content="https://www.datocms-assets.com/56687/1652242695-bpfdoor-deleted-binary.png?w=1000&amp;fit=max&amp;fm=jpg" /><link rel="preload" as="font" type="font/woff2" crossOrigin="anonymous" href="/static/webfonts/s/ibmplexsans/v13/zYX-KVElMYYaJe8bpLHnCwDKhdTuF6ZJ.woff2" /><link rel="preload" as="font" type="font/woff2" crossOrigin="anonymous" href="/static/webfonts/s/ibmplexsans/v13/zYXgKVElMYYaJe8bpLHnCwDKhdHeFQ.woff2" /><link rel="preload" as="font" type="font/woff2" crossOrigin="anonymous" href="/static/webfonts/s/ibmplexsans/v13/zYX9KVElMYYaJe8bpLHnCwDKjQ76AIFsdA.woff2" /><link rel="preload" as="font" type="font/woff2" crossOrigin="anonymous" href="/static/webfonts/s/monda/v14/TK3tWkYFABsmjsphPho.woff2" /><link rel="preload" as="font" type="font/woff2" crossOrigin="anonymous" href="/static/webfonts/s/monda/v14/TK3gWkYFABsmjsLaGw8Eneo.woff2" /><style>@font-face{font-display:swap;font-family:IBM Plex Sans;font-style:italic;font-weight:400;src:url("https://d33wubrfki0l68.cloudfront.net/a47b57fd5ba3060887832109413edb6acdb246ed/478fb/static/webfonts/s/ibmplexsans/v13/zyx-kvelmyyaje8bplhncwdkhdtuf6zj.woff2") format("woff2")}@font-face{font-display:swap;font-family:IBM Plex Sans;font-style:normal;font-weight:400;src:url("https://d33wubrfki0l68.cloudfront.net/d688e6d4db3d5ded8039208ec478049e971f4075/ed8f6/static/webfonts/s/ibmplexsans/v13/zyxgkvelmyyaje8bplhncwdkhdhefq.woff2") format("woff2")}@font-face{font-display:swap;font-family:IBM Plex Sans;font-style:normal;font-weight:600;src:url("https://d33wubrfki0l68.cloudfront.net/6d73e6d49b1e6313768d3a34b00d643ab0ac34b4/d183f/static/webfonts/s/ibmplexsans/v13/zyx9kvelmyyaje8bplhncwdkjq76aifsda.woff2") format("woff2")}@font-face{font-display:swap;font-family:IBM Plex Sans;font-style:italic;font-weight:400;src:url("https://d33wubrfki0l68.cloudfront.net/3cd6509d4844db3899938b3edd420daddbb79880/a7786/static/webfonts/s/ibmplexsans/v13/zyx-kvelmyyaje8bplhncwdkhdtuf6zp.woff") format("woff")}@font-face{font-display:swap;font-family:IBM Plex Sans;font-style:normal;font-weight:400;src:url("https://d33wubrfki0l68.cloudfront.net/e7d1609e02fe013879caf8b3496794c49b24ebaa/b5b87/static/webfonts/s/ibmplexsans/v13/zyxgkvelmyyaje8bplhncwdkhdheew.woff") format("woff")}@font-face{font-display:swap;font-family:IBM Plex Sans;font-style:normal;font-weight:600;src:url("https://d33wubrfki0l68.cloudfront.net/841470594f71b5b270f24ddf4fdf8a61d6a09ee1/6f323/static/webfonts/s/ibmplexsans/v13/zyx9kvelmyyaje8bplhncwdkjq76aifscg.woff") format("woff")}@font-face{font-display:swap;font-family:Monda;font-style:normal;font-weight:400;src:url("https://d33wubrfki0l68.cloudfront.net/524e328b13f56784db5d7a60bcb6568dd21b4a64/30fd5/static/webfonts/s/monda/v14/tk3twkyfabsmjsphpho.woff2") format("woff2")}@font-face{font-display:swap;font-family:Monda;font-style:normal;font-weight:700;src:url("https://d33wubrfki0l68.cloudfront.net/cf325627c752ad59c6b25723ba5d33b068c8c9a7/c6000/static/webfonts/s/monda/v14/tk3gwkyfabsmjslagw8eneo.woff2") format("woff2")}@font-face{font-display:swap;font-family:Monda;font-style:normal;font-weight:400;src:url("https://d33wubrfki0l68.cloudfront.net/cd182b26dc769770299752e728c9916940871ce9/6a399/static/webfonts/s/monda/v14/tk3twkyfabsmjsphphw.woff") format("woff")}@font-face{font-display:swap;font-family:Monda;font-style:normal;font-weight:700;src:url("https://d33wubrfki0l68.cloudfront.net/828ad2d1f3a38162c7c807f18333e3e5c97a5693/f9b25/static/webfonts/s/monda/v14/tk3gwkyfabsmjslagw8enew.woff") format("woff")}</style><style>.gatsby-image-wrapper{position:relative;overflow:hidden}.gatsby-image-wrapper picture.object-fit-polyfill{position:static!important}.gatsby-image-wrapper img{bottom:0;height:100%;left:0;margin:0;max-width:none;padding:0;position:absolute;right:0;top:0;width:100%;object-fit:cover}.gatsby-image-wrapper [data-main-image]{opacity:0;transform:translateZ(0);transition:opacity .25s linear;will-change:opacity}.gatsby-image-wrapper-constrained{display:inline-block;vertical-align:top}</style><noscript><style>.gatsby-image-wrapper noscript [data-main-image]{opacity:1!important}.gatsby-image-wrapper [data-placeholder-image]{opacity:0!important}</style></noscript><script type="module">const e="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;e&&document.body.addEventListener("load",(function(e){if(void 0===e.target.dataset.mainImage)return;if(void 0===e.target.dataset.gatsbyImageSsr)return;const t=e.target;let a=null,n=t;for(;null===a&&n;)void 0!==n.parentNode.dataset.gatsbyImageWrapper&&(a=n.parentNode),n=n.parentNode;const o=a.querySelector("[data-placeholder-image]"),r=new Image;r.src=t.currentSrc,r.decode().catch((()=>{})).then((()=>{t.style.opacity=1,o&&(o.style.opacity=0,o.style.transition="opacity 500ms linear")}))}),!0);</script><link rel="sitemap" type="application/xml" href="/sitemap/sitemap-index.xml" /><link rel="alternate" type="application/rss+xml" title="Sandfly Security Blog RSS Feed" href="/blog/rss.xml" /><link rel="preconnect" href="https://www.googletagmanager.com" /><link rel="dns-prefetch" href="https://www.googletagmanager.com" /><link as="script" rel="preload" href="/webpack-runtime-7a237243913e1c3537fa.js" /><link as="script" rel="preload" href="/framework-37f3235980163f3a0502.js" /><link as="script" rel="preload" href="/252f366e-4458bcdf9678f3e5d264.js" /><link as="script" rel="preload" href="/545f34e4-222e9b8aec85efb6ec28.js" /><link as="script" rel="preload" href="/1bfc9850-8f7c3f76a08c2178042b.js" /><link as="script" rel="preload" href="/0c428ae2-8cfc58f9628708c73fdf.js" /><link as="script" rel="preload" href="/d7eeaac4-9c0e24a908780f8d6714.js" /><link as="script" rel="preload" href="/dc6a8720040df98778fe970bf6c000a41750d3ae-9658f7f752126de65529.js" /><link as="script" rel="preload" href="/app-48ae15cb23f3d89f16ff.js" /><link as="script" rel="preload" href="/commons-f9f5fcc60d25b105667f.js" /><link as="script" rel="preload" href="/component---src-templates-post-tsx-c16b4e12703eba509130.js" /><link as="fetch" rel="preload" href="/page-data/blog/bpfdoor-an-evasive-linux-backdoor-technical-analysis/page-data.json" crossOrigin="anonymous" /><link as="fetch" rel="preload" href="/page-data/sq/d/1073642445.json" crossOrigin="anonymous" /><link as="fetch" rel="preload" href="/page-data/sq/d/1103654681.json" crossOrigin="anonymous" /><link as="fetch" rel="preload" href="/page-data/sq/d/1530575845.json" crossOrigin="anonymous" /><link as="fetch" rel="preload" href="/page-data/sq/d/1815332591.json" crossOrigin="anonymous" /><link as="fetch" rel="preload" href="/page-data/sq/d/2060295489.json" crossOrigin="anonymous" /><link as="fetch" rel="preload" href="/page-data/sq/d/2461549756.json" crossOrigin="anonymous" /><link as="fetch" rel="preload" href="/page-data/sq/d/3889418360.json" crossOrigin="anonymous" /><link as="fetch" rel="preload" href="/page-data/sq/d/3948011046.json" crossOrigin="anonymous" /><link as="fetch" rel="preload" href="/page-data/sq/d/717698143.json" crossOrigin="anonymous" /><link as="fetch" rel="preload" href="/page-data/sq/d/916489293.json" crossOrigin="anonymous" /><link as="fetch" rel="preload" href="/page-data/app-data.json" crossOrigin="anonymous" /></head><body><div id="___gatsby"><div style="outline: none;" tabIndex="-1" id="gatsby-focus-wrapper"><div id="layout" class="layout"><div data-focus-guard tabIndex="-1" style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"></div><div data-focus-guard tabIndex="-1" style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"></div><div data-focus-lock-disabled="disabled" data-focus-lock="sidebar"><div class="headroom-wrapper"><div class="headroom headroom--unfixed"><header class="ss--header"><div><div class="ss--notification ss--notification--gradient"><a href="/blog/sandfly-3-3-reporting-sso-veracode-certified-suspicious-ip-detection-and-more/"><div class="ss--notification__content"><div class="ss--notification__title">Sandfly 3.3 - Reporting, SSO, Veracode Certified and More...<span class="ss--notification__button"><div class="ss--notification__cta">Learn More</div><div class="ss--notification__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 16 16" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8z"></path></svg></div></span></div></div></a><button aria-label="Close Notification"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0V0z"></path><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"></path></svg></button></div></div><div class="ss--header__top"><div class="ss--header__container"><div class="ss--header__wrapper"><a class="ss--header__link ss--header__link--parent" href="/blog/">Blog</a><a href="https://support.sandflysecurity.com/support/home" class="ss--header__link">Support</a><a class="ss--header__link" href="/contact-us/">Contact Us</a></div></div></div><div class="ss--header__container"><div class="ss--header__wrapper"><div class="ss--header__logo"><a title="Sandfly Security Logo" href="/"><div class="ss--logo"><svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" viewBox="0 0 346 111"><defs><linearGradient x1="25.173%" y1="55.138%" x2="3.088%" y2="48.072%" id="b"><stop stop-color="#3FB183" offset="0%"></stop><stop stop-color="#1BACA2" offset="100%"></stop></linearGradient><path d="M30.066 86.666a1.047 1.047 0 0 1 1.325.663l5.214 15.655 9.805 5.488a1.048 1.048 0 0 1-1.023 1.827l-10.158-5.686a1.048 1.048 0 0 1-.483-.582L29.404 87.99a1.047 1.047 0 0 1 .662-1.324Zm12.319-7.747c.34-.213.772-.213 1.11 0l9.33 5.84c.41.257.592.763.437 1.222l-3.065 9.085 10.68 5.709 4.486-13.447a1.048 1.048 0 0 1 1.987.663l-4.878 14.623c-.02.056-.043.11-.07.162l-.008.01a1.024 1.024 0 0 1-.153.211l-.017.02a1.15 1.15 0 0 1-.13.112l-6.853 4.992a1.053 1.053 0 0 1-1.105.079l-10.951-5.771a2.77 2.77 0 1 1 1.173-1.749l10.178 5.364 4.976-3.625-11.084-5.924a1.046 1.046 0 0 1-.5-1.258l3.085-9.142-8.072-5.054-6.126 3.836a1.048 1.048 0 0 1-1.112-1.775l6.682-4.183Zm19-56.087c.337-.014.656.131.865.392l5.442 6.803c.288.36.307.865.047 1.246l-6.655 9.72 1.15 8.128 8.477 5.308c.253.159.427.418.477.713l2.147 12.737a2.768 2.768 0 0 1-.732 5.439 2.77 2.77 0 0 1-1.35-5.189l-2.052-12.175-8.491-5.316a1.046 1.046 0 0 1-.481-.741l-1.276-9.013a1.053 1.053 0 0 1 .173-.738l6.447-9.417-4.06-5.075-8.993 13.595 4.879 34.49 37.367 23.395-13.6-45.4a2.769 2.769 0 1 1 3.123-2.745c0 .901-.432 1.7-1.098 2.205l14.378 48.002a1.05 1.05 0 0 1-1.003 1.348c-.192 0-.385-.053-.555-.16L55.874 75.256a1.049 1.049 0 0 1-.481-.741l-3.395-24.007h-6.441L42.16 74.515c-.043.306-.22.577-.481.741L1.544 100.384A1.047 1.047 0 0 1 0 99.844v-.701l14.364-47.948a2.765 2.765 0 0 1-1.093-2.015l-.006-.191a2.77 2.77 0 1 1 3.123 2.745l-13.6 45.4 37.368-23.395 4.879-34.49-8.993-13.595-4.061 5.075 6.447 9.417c.147.215.209.479.173.738l-1.275 9.013c-.043.306-.22.577-.481.741l-8.492 5.316L26.3 68.13a2.77 2.77 0 1 1-2.081-.251l2.147-12.737c.049-.295.223-.554.477-.713l8.477-5.308 1.149-8.128-6.654-9.72c-.26-.38-.242-.886.046-1.246l5.442-6.803a1.05 1.05 0 0 1 1.69.076L47 38.424c.14.213.2.471.164.725l-1.41 9.963H51.8l-1.41-9.964c-.036-.253.023-.51.164-.724L60.559 23.3c.185-.279.492-.453.826-.468ZM49.027 73.585a2.77 2.77 0 0 1 2.716 3.316l9.739 6.098c.41.258.59.763.437 1.222l-3.278 9.716a1.049 1.049 0 0 1-1.985-.67l3.014-8.931-9.086-5.689a2.77 2.77 0 1 1-1.557-5.062Zm-23.63-39.068a2.77 2.77 0 0 1 .265 5.527L14.329 77.88l2.408 4.245 15.267-9.559 2.229-15.753a1.047 1.047 0 1 1 2.073.294L34.01 73.341c-.043.306-.22.577-.481.741L16.92 84.48a1.048 1.048 0 0 1-1.466-.371l-3.168-5.585a1.05 1.05 0 0 1-.093-.817l11.463-38.266a2.77 2.77 0 0 1 1.74-4.924h.001Zm46.76 0a2.77 2.77 0 0 1 1.74 4.924L85.36 77.707a1.05 1.05 0 0 1-.092.817l-3.17 5.585a1.047 1.047 0 0 1-1.465.371L64.026 74.082a1.05 1.05 0 0 1-.482-.741l-2.302-16.277a1.048 1.048 0 0 1 2.074-.294l2.234 15.796 15.267 9.559 2.409-4.245-11.334-37.836a2.77 2.77 0 0 1 .266-5.527h-.001ZM57.938 18.05c.32.214.407.647.193.968l-8.655 12.957a.696.696 0 0 1-.58.31h-.001a.7.7 0 0 1-.581-.313L39.73 19.016a.698.698 0 0 1 1.163-.771l4.118 6.215 4.136-6.139a.72.72 0 0 1 1.194.801l-4.471 6.635 3.027 4.57 8.072-12.084a.698.698 0 0 1 .968-.193h.001ZM50.63 0c.316 0 .616.143.815.389l6.168 7.623a3.464 3.464 0 1 1-2.171 3.938h-13.33a3.462 3.462 0 1 1-2.151-3.927l6.105-7.63c.198-.248.499-.393.817-.393h3.747Zm-.501 2.094h-2.742l-5.788 7.235c.245.365.422.779.514 1.225h13.329c.093-.453.276-.873.528-1.243l-5.841-7.217Z" id="a"></path></defs><g fill="none" fill-rule="evenodd"><mask id="c" fill="#fff"><use xlink:href="#a"></use></mask><polygon fill="url(#b)" fill-rule="nonzero" mask="url(#c)" points=".001 110.433 345.182 110.433 345.182 0 .001 0"></polygon><path d="M141.387 30.594h-6.768a5.984 5.984 0 0 1-.054-.652c-.161-1.783-.615-2.904-1.364-3.361-.75-.457-2.515-.686-5.297-.686-3.282 0-5.426.263-6.433.791-1.008.527-1.512 1.636-1.512 3.326 0 2.001.41 3.203 1.23 3.606.82.403 3.532.713 8.133.93 5.44.264 8.957.939 10.553 2.024 1.597 1.086 2.395 3.342 2.395 6.769 0 4.219-.937 6.944-2.81 8.177-1.872 1.233-6.001 1.85-12.385 1.85-5.743 0-9.555-.605-11.436-1.815-1.882-1.21-2.823-3.66-2.823-7.351l-.027-1.163h6.742l.027.675c0 2.217.445 3.575 1.337 4.071.89.496 3.326.744 7.303.744 3.104 0 5.083-.287 5.939-.861.857-.573 1.284-1.899 1.284-3.978 0-1.535-.325-2.555-.976-3.058-.651-.504-2.056-.811-4.213-.919l-3.826-.21c-5.778-.294-9.47-.992-11.075-2.093-1.605-1.101-2.408-3.467-2.408-7.095 0-3.707.967-6.177 2.902-7.409 1.935-1.234 5.8-1.85 11.597-1.85 5.494 0 9.194.566 11.102 1.698 1.908 1.132 2.863 3.342 2.863 6.63v1.21m26.19 11.957-6.314-16.54-6.206 16.54h12.52Zm1.605 4.443h-15.757l-2.274 6.094h-7.33l12.145-31.753h10.407l12.332 31.753h-7.196l-2.327-6.094Zm46.575-25.659v31.753h-11.744L193.58 35.665c-.517-.868-1.33-2.388-2.435-4.56l-1.177-2.279-1.15-2.28h-.268l.108 2.094.08 2.07.053 4.164v18.214h-6.93V21.335h11.745l9.497 16.098c.838 1.427 1.81 3.156 2.916 5.187l1.392 2.582 1.39 2.606h.24l-.16-4.094-.052-4.095V21.335h6.928m13.349 26.682h9.87c3.318 0 5.463-.663 6.436-1.989.97-1.326 1.457-4.253 1.457-8.781 0-4.684-.437-7.661-1.311-8.933-.874-1.272-2.925-1.908-6.153-1.908h-10.3v21.611h.001Zm-6.93 5.071V21.335h17.952c5.1 0 8.67.97 10.714 2.908 2.042 1.939 3.063 5.335 3.063 10.189 0 7.925-.821 13.015-2.461 15.272-1.641 2.256-5.342 3.384-11.102 3.384h-18.166Z" fill="currentColor" fill-rule="nonzero"></path><polyline fill="currentColor" fill-rule="nonzero" points="265.89 26.406 265.89 34.967 282.262 34.967 282.262 40.038 265.89 40.038 265.89 53.088 258.961 53.088 258.961 21.335 283.145 21.335 283.145 26.406 265.89 26.406"></polyline><polyline fill="currentColor" fill-rule="nonzero" points="294.3 21.335 294.3 47.692 311.421 47.692 311.421 53.088 287.371 53.088 287.371 21.335 294.3 21.335"></polyline><path d="m345.182 21.335-13.536 19.634v12.119h-6.93V40.969l-13.161-19.634h8.026l5.51 8.375c.303.465.82 1.326 1.552 2.582l.776 1.279.749 1.28h.187l1.552-2.559c.66-1.148 1.186-2.008 1.578-2.582l5.564-8.375h8.133M135.445 70.434h-3.46c0-2.163-.413-3.536-1.242-4.119-.83-.583-2.781-.875-5.855-.875-3.648 0-6 .279-7.054.836-1.055.557-1.583 1.799-1.583 3.725 0 2.163.415 3.48 1.244 3.952.829.471 3.293.793 7.393.963 4.807.184 7.863.714 9.167 1.592 1.303.878 1.956 2.844 1.956 5.898 0 3.302-.751 5.439-2.25 6.408-1.5.97-4.812 1.455-9.936 1.455-4.446 0-7.404-.488-8.873-1.465-1.47-.976-2.205-2.945-2.205-5.907l-.022-1.199h3.459v.668c0 2.399.422 3.89 1.266 4.473.844.583 3.007.874 6.488.874 3.994 0 6.45-.291 7.37-.874.919-.583 1.379-2.14 1.379-4.669 0-1.638-.313-2.729-.938-3.273-.626-.544-1.933-.868-3.923-.973l-3.617-.158-3.436-.157c-5.23-.315-7.845-2.674-7.845-7.077 0-3.054.76-5.092 2.284-6.114 1.522-1.022 4.559-1.533 9.11-1.533 4.612 0 7.619.475 9.02 1.425 1.403.951 2.103 2.991 2.103 6.124" fill="currentColor" fill-rule="nonzero"></path><polyline fill="currentColor" fill-rule="nonzero" points="147.893 65.716 147.893 74.857 163.561 74.857 163.561 77.412 147.893 77.412 147.893 87.438 164.239 87.438 164.239 89.994 144.413 89.994 144.413 63.16 164.239 63.16 164.239 65.716 147.893 65.716"></polyline><path d="M194.412 81.03h3.459v1.022c0 3.656-.716 5.94-2.147 6.851-1.433.911-5.035 1.366-10.807 1.366-5.17 0-8.455-.803-9.857-2.408-1.401-1.605-2.102-5.383-2.102-11.333 0-4.652.158-7.578.474-8.778.317-1.199 1.222-2.27 2.713-3.214 1.748-1.101 5.524-1.651 11.327-1.651 3.933 0 6.582.531 7.946 1.592 1.364 1.062 2.046 3.113 2.046 6.153l.022.728h-3.458l-.023-.826c0-2.162-.403-3.551-1.21-4.168-.806-.616-2.626-.924-5.46-.924-4.973 0-8.01.361-9.11 1.082-1.1.72-1.65 2.719-1.65 5.995 0 7.536.369 11.953 1.107 13.25.739 1.298 3.264 1.946 7.574 1.946 4.1 0 6.658-.281 7.675-.845 1.017-.563 1.527-1.978 1.527-4.246l-.046-1.592m33.835-17.87h3.482v18.794c0 3.407-.788 5.645-2.363 6.713-1.575 1.068-4.88 1.602-9.913 1.602-4.718 0-7.924-.514-9.62-1.543-1.695-1.029-2.542-2.985-2.542-5.868V63.16h3.48v18.794c0 2.542.476 4.138 1.425 4.786.95.649 3.286.973 7.008.973 4.039 0 6.556-.317 7.55-.953.996-.636 1.493-2.238 1.493-4.806V63.16m18.282 13.407h10.06c2.652 0 4.46-.35 5.425-1.052.965-.7 1.447-2.021 1.447-3.961 0-2.424-.358-4.003-1.073-4.738-.716-.733-2.25-1.1-4.601-1.1h-11.258v10.851Zm-3.482 13.427V63.16h14.695c3.316 0 5.652.57 7.008 1.71 1.357 1.14 2.035 3.12 2.035 5.937 0 2.477-.37 4.204-1.108 5.18-.74.977-2.148 1.609-4.227 1.897v.059c3.27.21 4.905 1.94 4.905 5.19v6.861h-3.481v-6.173c0-3.132-1.56-4.698-4.68-4.698h-11.665v10.871h-3.482Z" fill="currentColor" fill-rule="nonzero"></path><polygon fill="currentColor" fill-rule="nonzero" points="277.357 89.994 280.839 89.994 280.839 63.16 277.357 63.16"></polygon><polyline fill="currentColor" fill-rule="nonzero" points="303.008 65.971 303.008 89.994 299.527 89.994 299.527 65.971 289.467 65.971 289.467 63.16 312.978 63.16 312.978 65.971 303.008 65.971"></polyline><path d="m344.892 63.16-11.665 15.628v11.206h-3.482V78.788L318.374 63.16h4.046l6.624 9.063 1.266 1.749c.166.21.377.498.633.865l.61.885h.09l.612-.885.61-.865 1.289-1.749 6.6-9.063h4.138" fill="currentColor" fill-rule="nonzero"></path></g></svg></div></a></div><div class="ss--header__menu"><nav><ul class="ss--menu__list"><li class="ss--menu__item"><button aria-haspopup="true" aria-controls="menu-0-box" aria-expanded="false" id="menu-0-button" tabIndex="0" class="ss--menu__toggle"><span class="ss--menu__link">Platform<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"></path></svg></span><div aria-labelledby="menu-0-button" id="menu-0-box" class="ss--drop-down ss--drop-down--closed"><ul class="ss--drop-down__list" style="opacity: 0; transform: translateY(-32px) translateZ(0);"><li class="ss--menu-item" style="opacity: 0; transform: translateY(-16px) translateZ(0);"><a tabIndex="-1" class="ss--button ss--button--alignment-left ss--button--color-accent ss--button--style-solid ss--button--menu-item ss--button--inverse" href="/platform/why-sandfly/"><span><span>Why Sandfly?</span></span></a></li><li class="ss--menu-item" style="opacity: 0; transform: translateY(-16px) translateZ(0);"><a tabIndex="-1" class="ss--button ss--button--alignment-left ss--button--color-accent ss--button--style-solid ss--button--menu-item ss--button--inverse" href="/platform/how-sandfly-works/"><span><span>How Sandfly Works</span></span></a></li><li class="ss--menu-item" style="opacity: 0; transform: translateY(-16px) translateZ(0);"><a tabIndex="-1" class="ss--button ss--button--alignment-left ss--button--color-accent ss--button--style-solid ss--button--menu-item ss--button--inverse" href="/platform/threats-detected/"><span><span>Linux Threats Detected</span></span></a></li><li class="ss--menu-item" style="opacity: 0; transform: translateY(-16px) translateZ(0);"><a tabIndex="-1" class="ss--button ss--button--alignment-left ss--button--color-accent ss--button--style-solid ss--button--menu-item ss--button--inverse" href="/platform/walk-through/"><span><span>Walk Through</span></span></a></li></ul></div></button></li><li class="ss--menu__item"><button aria-haspopup="true" aria-controls="menu-1-box" aria-expanded="false" id="menu-1-button" tabIndex="0" class="ss--menu__toggle"><span class="ss--menu__link">Resources<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"></path></svg></span><div aria-labelledby="menu-1-button" id="menu-1-box" class="ss--drop-down ss--drop-down--closed"><ul class="ss--drop-down__list" style="opacity: 0; transform: translateY(-32px) translateZ(0);"><li class="ss--menu-item" style="opacity: 0; transform: translateY(-16px) translateZ(0);"><a tabIndex="-1" class="ss--button ss--button--alignment-left ss--button--color-accent ss--button--style-solid ss--button--menu-item ss--button--inverse" href="/resources/product-faqs/"><span><span>Product FAQs</span></span></a></li><li class="ss--menu-item" style="opacity: 0; transform: translateY(-16px) translateZ(0);"><a href="https://support.sandflysecurity.com/support/solutions/72000030324" target="_blank" rel="noopener noreferrer" class="ss--button ss--button--alignment-left ss--button--color-accent ss--button--style-solid ss--button--menu-item ss--button--inverse"><span><span>Product Documentation</span></span></a></li></ul></div></button></li><li class="ss--menu__item"><button aria-haspopup="true" aria-controls="menu-2-box" aria-expanded="false" id="menu-2-button" tabIndex="0" class="ss--menu__toggle"><span class="ss--menu__link">Customers<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"></path></svg></span><div aria-labelledby="menu-2-button" id="menu-2-box" class="ss--drop-down ss--drop-down--closed"><ul class="ss--drop-down__list" style="opacity: 0; transform: translateY(-32px) translateZ(0);"><li class="ss--menu-item" style="opacity: 0; transform: translateY(-16px) translateZ(0);"><a tabIndex="-1" class="ss--button ss--button--alignment-left ss--button--color-accent ss--button--style-solid ss--button--menu-item ss--button--inverse" href="/customers/testimonials/"><span><span>Testimonials</span></span></a></li><li class="ss--menu-item" style="opacity: 0; transform: translateY(-16px) translateZ(0);"><a tabIndex="-1" class="ss--button ss--button--alignment-left ss--button--color-accent ss--button--style-solid ss--button--menu-item ss--button--inverse" href="/customers/case-studies/"><span><span>Case Studies</span></span></a></li></ul></div></button></li><li class="ss--menu__item"><button aria-haspopup="true" aria-controls="menu-3-box" aria-expanded="false" id="menu-3-button" tabIndex="0" class="ss--menu__toggle"><span class="ss--menu__link">About Us<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"></path></svg></span><div aria-labelledby="menu-3-button" id="menu-3-box" class="ss--drop-down ss--drop-down--closed"><ul class="ss--drop-down__list" style="opacity: 0; transform: translateY(-32px) translateZ(0);"><li class="ss--menu-item" style="opacity: 0; transform: translateY(-16px) translateZ(0);"><a tabIndex="-1" class="ss--button ss--button--alignment-left ss--button--color-accent ss--button--style-solid ss--button--menu-item ss--button--inverse" href="/about-us/our-story/"><span><span>Our Story</span></span></a></li><li class="ss--menu-item" style="opacity: 0; transform: translateY(-16px) translateZ(0);"><a tabIndex="-1" class="ss--button ss--button--alignment-left ss--button--color-accent ss--button--style-solid ss--button--menu-item ss--button--inverse" href="/about-us/partner/"><span><span>Partners And MSSPs</span></span></a></li><li class="ss--menu-item" style="opacity: 0; transform: translateY(-16px) translateZ(0);"><a tabIndex="-1" class="ss--button ss--button--alignment-left ss--button--color-accent ss--button--style-solid ss--button--menu-item ss--button--inverse" href="/under-attack/"><span><span>Under Attack? </span></span></a></li><li class="ss--menu-item" style="opacity: 0; transform: translateY(-16px) translateZ(0);"><a tabIndex="-1" class="ss--button ss--button--alignment-left ss--button--color-accent ss--button--style-solid ss--button--menu-item ss--button--inverse" href="/contact-us/"><span><span>Contact Us </span></span></a></li></ul></div></button></li></ul></nav></div><div class="ss--header__cta"><a class="ss--button ss--button--alignment-left ss--button--color-white ss--button--elevated ss--button--style-bordered" href="/get-sandfly/"><span>Get Sandfly</span></a></div><div class="ss--header__icon"><button aria-label="Toggle Menu" class="ss--menu-icon"><svg viewBox="0 0 40 41"><rect width="18" height="2.25" rx=".5" x="22" y="13"></rect><rect width="18" height="2.25" rx=".5" x="22" y="19" opacity="1"></rect><rect width="18" height="2.25" rx=".5" x="22" y="25"></rect></svg></button></div></div></div></header></div></div></div><div data-focus-guard tabIndex="-1" style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"></div><div class="layout__content"><main><nav aria-label="Breadcrumb" class="ss--breadcrumbs"><ul class="ss--breadcrumbs__list"><li class="ss--breadcrumbs__item"><a href="/blog/">Blog</a></li><li aria-current="page" class="ss--breadcrumbs__item"><a aria-current="page" class href="/blog/bpfdoor-an-evasive-linux-backdoor-technical-analysis/" class>BPFDoor - An Evasive Linux Backdoor Technical Analysis</a></li></ul></nav><div class="ss--content ss--content--gutters ss--content--text-align-left ss--content--width-small ss--content--improved-typography"><div class="ss--spacer "></div><div><h1>BPFDoor - An Evasive Linux Backdoor Technical Analysis</h1><p class="ss--post-intro__tags"><a class="ss--post-intro__tag" href="/blog/tag/malware/">Malware</a> <a class="ss--post-intro__tag" href="/blog/tag/linux-forensics/">Linux Forensics</a></p><div class="ss--post-intro__meta"><dl class="ss--post-intro__date"><dt>Date</dt><dd>May 11, 2022</dd></dl><dl><dt>Author</dt><dd>The Sandfly Security Team</dd></dl></div></div><div class="ss--spacer "></div><p>Recently Kevin Beaumont revealed a new evasive backdoor targeting Linux associated with the Chinese Red Menshen threat actors. In his <a href="https://doublepulsar.com/bpfdoor-an-active-chinese-global-surveillance-tool-54b078f1a896">article</a> he reveals that this backdoor has been operating globally for many years with potentially thousands of instances already deployed. The backdoor has also been noted by investigators at PricewaterhouseCoopers in their latest <a href="https://www.pwc.com/gx/en/issues/cybersecurity/cyber-threat-intelligence/cyber-year-in-retrospect/yir-cyber-threats-report-download.pdf">Cyber Threat Intelligence Retrospect Report</a> (pg. 36).</p><p>The source for this backdoor was<a href="https://pastebin.com/kmmJuuQP"> posted by anonymously</a> and Sandfly researchers are able to provide the following in-depth technical analysis. At a high level, it does the following:</p><ul><li><p>Goes memory resident and deploys anti-forensics and evasion to hide.</p></li><li><p>Loads a Berkeley Packet Filter (BPF) sniffer allowing it to efficiently watch traffic and work in front of any locally running firewalls to see packets (hence BPFDoor).</p></li><li><p>Upon receiving a special packet, it will modify the local firewall to allow the attacker IP address to access resources such as a spawned shell or connect back bindshell.</p></li><li><p>Operations are hidden with process masquerading to avoid detection.</p></li></ul><p>While the malware takes steps to evade casual observation, it is easily seen if you know where and how to look. We'll review the above and provide detection tips.</p><h1>Source Build Size and Compatibility</h1><p>The BPFDoor source is small, focused and well written. While the sample we reviewed was Linux specific, with some small changes it could easily be ported to other platforms (a Solaris binary reportedly exists). BPF is widely available across operating systems and the core shell functions would likely work across platforms with little modification. </p><p>The dynamically linked binary is small at about 35K on Ubuntu:</p><pre><code>-rwxr-xr-x  1 root root   34952 May 11 00:03 bpfdoor</code></pre><p>Statically linked it would grow to about 1MB, but the dynamically linked version would likely work on most modern Linux distributions. Cross compiling for various CPUs is also possible so this implant would likely work on embedded Linux devices as well. </p><h1>Implant Operation Steps</h1><p>The binary itself just needs to be downloaded onto the victim and run. It doesn't matter how or where it gets to the host as it takes care of moving itself to a suitable area once run to remain resident. However, the binary does need <em>root</em> permissions to run. </p><p>When run, the binary has an initialization sequence as follows:</p><p>1) Copy binary to the <em>/dev/shm</em> directory (Linux ramdisk).</p><p>2) Rename and run itself as <em>/dev/shm/kdmtmpflush.</em></p><p>3) Fork itself and run fork with &quot;--init&quot; flag which tells itself to execute secondary clean-up operations and go resident.</p><p>4) The forked version <a href="https://attack.mitre.org/techniques/T1070/006/">timestomps</a> the binary file <em>/dev/shm/kdmtmpflush </em>and initiates packet capture loop.</p><p>5) The forked version creates a dropper at <em>/var/run/haldrund.pid </em>to mark it is resident and prevent multiple starts.</p><p>6) The original execution process deletes the timestomped <em>/dev/shm/kdmtmpflush </em>and exits.</p><p>7) The forked version remains resident and monitors traffic for magic packet to initiate attacker operations such as a bindshell. </p><h1>Persistence</h1><p>The implant itself has no persistence mechanisms as it is highly focused on a single task. Persistence would need to be initiated by the attacker in some other way such as <em>rc </em>or <em>init</em> scripts or scheduled tasks such as with <em>crontab</em>. The initial report referenced above indicates that persistence scripts have been found.</p><p>The implant uses <em>/dev/shm</em> on Linux. This is a ramdisk and is cleared out on every reboot. For persistence reasons, the implant will need to be somewhere else on the host to survive reboots or be inserted again remotely. </p><p>Incident response teams that find this implant operating should <strong>assume the real binary is somewhere else on the file system.</strong> Check all system boot scripts for unusual references to binaries or paths.</p><h1>Timestomping</h1><p>The binary copies itself to <em>/dev/shm/kdmtmpflush</em> which is only in RAM and clears out every reboot. The interesting part of the implant is that it sets a bogus time to timestomp the binary before deletion. The relevant code is below:</p><pre data-language="c"><code>tv[0].tv_sec = 1225394236;
tv[0].tv_usec = 0;

tv[1].tv_sec = 1225394236;
tv[1].tv_usec = 0;

utimes(file, tv);
</code></pre><p>The date is set to 1225394236 seconds from epoch which translates to: <strong>Thursday, October 30, 2008 7:17:16 PM</strong> (GMT)</p><p>We did some searches to see if this date has any significance but didn't see anything obvious. It could have some significance to the author or could be random. </p><p>The interesting part about this is the timestomp happens by the forked process before the main process tries to delete the binary. We assume this is a failsafe mechanism. If the implant should fail to load and not delete itself from <em>/dev/shm/kdmtmpflush</em> then the file left behind will have an innocuous looking time on it that masks when it was created. It would also make incident response harder if you are looking for recently created files (this one looks like it was created 14 years ago). </p><p><div ariaRole="button" ariaLabel="Toggle Lightbox" class="ss--image ss--image--elevated ss--image--width-medium ss--image--lightbox"><div data-gatsby-image-wrapper class="gatsby-image-wrapper gatsby-image-wrapper-constrained ss--image__image"><div style="max-width: 728px; display: block;"><img alt role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height='196' width='728' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;" /></div><img aria-hidden="true" data-placeholder-image style="opacity: 1; transition: opacity 500ms linear;" decoding="async" src="" alt /><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" data-src="https://www.datocms-assets.com/56687/1652229062-bpfdoor-timestomp-binary-before-deletion.png?auto=format&amp;fit=crop&amp;w=728" data-srcset="https://www.datocms-assets.com/56687/1652229062-bpfdoor-timestomp-binary-before-deletion.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652229062-bpfdoor-timestomp-binary-before-deletion.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652229062-bpfdoor-timestomp-binary-before-deletion.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="BPFDoor implant timestomping." /><noscript><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" src="https://www.datocms-assets.com/56687/1652229062-bpfdoor-timestomp-binary-before-deletion.png?auto=format&amp;fit=crop&amp;w=728" srcSet="https://www.datocms-assets.com/56687/1652229062-bpfdoor-timestomp-binary-before-deletion.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652229062-bpfdoor-timestomp-binary-before-deletion.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652229062-bpfdoor-timestomp-binary-before-deletion.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="BPFDoor implant timestomping." /></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}</script></div><span class="ss--image__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></span></div></p><h1>PID Dropper</h1><p>The implant creates a zero byte PID file at <em>/var/run/haldrund.pid</em>. This file is deleted if the implant terminates normally, but if there is a problem such as a hard shutdown or crash, the file may be left behind. The implant will not start if this file is present as it is used to mark that it may already be running.</p><h1>Binary Deletion</h1><p>After the binary starts, it deletes itself making recovery harder. However, recovering a deleted process binary on Linux is trivial once it is running (<a href="https://www.sandflysecurity.com/blog/how-to-recover-a-deleted-binary-from-active-linux-malware/">see our article on how to do it</a>). But the main thing deletion does is allow the binary to avoid detection by malware scanners that rely on file scanning. The binary is simply not on the disk to be scanned and if the main binary is hidden/encrypted on the device for persistence it would be very hard to find. </p><p>However on Linux a deleted process binary is extremely suspicious. If you search for any kind of process with a deleted binary then it stands out:</p><pre><code>ls -alR /proc/*/exe 2&gt; /dev/null | grep deleted</code></pre><p><div ariaRole="button" ariaLabel="Toggle Lightbox" class="ss--image ss--image--elevated ss--image--width-medium ss--image--lightbox"><div data-gatsby-image-wrapper class="gatsby-image-wrapper gatsby-image-wrapper-constrained ss--image__image"><div style="max-width: 728px; display: block;"><img alt role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height='100' width='728' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;" /></div><img aria-hidden="true" data-placeholder-image style="opacity: 1; transition: opacity 500ms linear;" decoding="async" src="" alt /><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" data-src="https://www.datocms-assets.com/56687/1652229749-bpfdoor-process-deleted-command-line.png?auto=format&amp;fit=crop&amp;w=728" data-srcset="https://www.datocms-assets.com/56687/1652229749-bpfdoor-process-deleted-command-line.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652229749-bpfdoor-process-deleted-command-line.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652229749-bpfdoor-process-deleted-command-line.png?auto=format&amp;fit=crop&amp;w=728 728w" alt /><noscript><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" src="https://www.datocms-assets.com/56687/1652229749-bpfdoor-process-deleted-command-line.png?auto=format&amp;fit=crop&amp;w=728" srcSet="https://www.datocms-assets.com/56687/1652229749-bpfdoor-process-deleted-command-line.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652229749-bpfdoor-process-deleted-command-line.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652229749-bpfdoor-process-deleted-command-line.png?auto=format&amp;fit=crop&amp;w=728 728w" alt /></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}</script></div><span class="ss--image__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></span></div></p><p>If you are using Sandfly to protect your Linux systems you will have received multiple automated alerts about a suspicious binary running. The red arrow shows that the process is masquerading as something else. We'll talk about that in a bit.</p><p><div ariaRole="button" ariaLabel="Toggle Lightbox" class="ss--image ss--image--elevated ss--image--width-medium ss--image--lightbox"><div data-gatsby-image-wrapper class="gatsby-image-wrapper gatsby-image-wrapper-constrained ss--image__image"><div style="max-width: 728px; display: block;"><img alt role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height='568' width='728' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;" /></div><img aria-hidden="true" data-placeholder-image style="opacity: 1; transition: opacity 500ms linear;" decoding="async" src="" alt /><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" data-src="https://www.datocms-assets.com/56687/1652242695-bpfdoor-deleted-binary.png?auto=format&amp;fit=crop&amp;w=728" data-srcset="https://www.datocms-assets.com/56687/1652242695-bpfdoor-deleted-binary.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652242695-bpfdoor-deleted-binary.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652242695-bpfdoor-deleted-binary.png?auto=format&amp;fit=crop&amp;w=728 728w" alt /><noscript><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" src="https://www.datocms-assets.com/56687/1652242695-bpfdoor-deleted-binary.png?auto=format&amp;fit=crop&amp;w=728" srcSet="https://www.datocms-assets.com/56687/1652242695-bpfdoor-deleted-binary.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652242695-bpfdoor-deleted-binary.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652242695-bpfdoor-deleted-binary.png?auto=format&amp;fit=crop&amp;w=728 728w" alt /></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}</script></div><span class="ss--image__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></span></div></p><p>In general, any process deleting its binary after running is going to be malicious. </p><h1>Masquerading</h1><p>The binary masquerades its name by selecting from one of 10 names randomly:</p><pre><code>/sbin/udevd -d
/sbin/mingetty /dev/tty7
/usr/sbin/console-kit-daemon --no-daemon
hald-addon-acpi: listening on acpi kernel interface /proc/acpi/event
dbus-daemon --system
hald-runner
pickup -l -t fifo -u
avahi-daemon: chroot helper
/sbin/auditd -n
/usr/lib/systemd/systemd-journald</code></pre><p>The names are made to look like common Linux system daemons. The implant overwrites the argv[0] value which is used by the Linux <em>/proc</em> filesystem to determine the command line and command name to show for each process. By doing this, when you run commands like <em>ps</em> you will see the bogus name. Below you can see the process running under the masquerade name <em>dbus-daemon --system.</em></p><p><div ariaRole="button" ariaLabel="Toggle Lightbox" class="ss--image ss--image--elevated ss--image--width-medium ss--image--lightbox"><div data-gatsby-image-wrapper class="gatsby-image-wrapper gatsby-image-wrapper-constrained ss--image__image"><div style="max-width: 728px; display: block;"><img alt role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height='355' width='728' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;" /></div><img aria-hidden="true" data-placeholder-image style="opacity: 1; transition: opacity 500ms linear;" decoding="async" src="" alt /><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" data-src="https://www.datocms-assets.com/56687/1652230613-bpfdoor-ps-listing.png?auto=format&amp;fit=crop&amp;w=728" data-srcset="https://www.datocms-assets.com/56687/1652230613-bpfdoor-ps-listing.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652230613-bpfdoor-ps-listing.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652230613-bpfdoor-ps-listing.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="BPFDoor Masquerading as dbus-daemon" /><noscript><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" src="https://www.datocms-assets.com/56687/1652230613-bpfdoor-ps-listing.png?auto=format&amp;fit=crop&amp;w=728" srcSet="https://www.datocms-assets.com/56687/1652230613-bpfdoor-ps-listing.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652230613-bpfdoor-ps-listing.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652230613-bpfdoor-ps-listing.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="BPFDoor Masquerading as dbus-daemon" /></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}</script></div><span class="ss--image__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></span></div></p><p>This masquerading tactic has been around for a while. While it works, the real process name is still visible inside Sandfly with the masqueraded versions also showing. This kind of difference in real process name vs. the command line values indicates also there is a problem. </p><p><div ariaRole="button" ariaLabel="Toggle Lightbox" class="ss--image ss--image--elevated ss--image--width-medium ss--image--lightbox"><div data-gatsby-image-wrapper class="gatsby-image-wrapper gatsby-image-wrapper-constrained ss--image__image"><div style="max-width: 728px; display: block;"><img alt role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height='404' width='728' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;" /></div><img aria-hidden="true" data-placeholder-image style="opacity: 1; transition: opacity 500ms linear;" decoding="async" src="" alt /><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" data-src="https://www.datocms-assets.com/56687/1652230838-bpfdoor-sandfly-hunter-real.png?auto=format&amp;fit=crop&amp;w=728" data-srcset="https://www.datocms-assets.com/56687/1652230838-bpfdoor-sandfly-hunter-real.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652230838-bpfdoor-sandfly-hunter-real.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652230838-bpfdoor-sandfly-hunter-real.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="Sandfly shows real process name vs. masquerading values for BPFDoor" /><noscript><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" src="https://www.datocms-assets.com/56687/1652230838-bpfdoor-sandfly-hunter-real.png?auto=format&amp;fit=crop&amp;w=728" srcSet="https://www.datocms-assets.com/56687/1652230838-bpfdoor-sandfly-hunter-real.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652230838-bpfdoor-sandfly-hunter-real.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652230838-bpfdoor-sandfly-hunter-real.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="Sandfly shows real process name vs. masquerading values for BPFDoor" /></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}</script></div><span class="ss--image__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></span></div></p><p>If you find a suspicious process ID (PID), you can quickly investigate what the real name may be by going to <em>/proc/&lt;PID&gt;</em> and doing a simple <em>ls</em> command:</p><pre><code>cd /proc/&lt;PID&gt;
ls -al</code></pre><p>You will see the <em>exe</em> link which will be pointing to the real binary location which can confirm at least what the binary was called when started. Also you'll see the timestamp on the file is when the binary was started which can help bracket the time of intrusion. Linux also helpfully labels the binary as &quot;(deleted)&quot;.</p><p><div ariaRole="button" ariaLabel="Toggle Lightbox" class="ss--image ss--image--elevated ss--image--width-medium ss--image--lightbox"><div data-gatsby-image-wrapper class="gatsby-image-wrapper gatsby-image-wrapper-constrained ss--image__image"><div style="max-width: 728px; display: block;"><img alt role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height='400' width='728' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;" /></div><img aria-hidden="true" data-placeholder-image style="opacity: 1; transition: opacity 500ms linear;" decoding="async" src="" alt /><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" data-src="https://www.datocms-assets.com/56687/1652231140-bpfdoor-proc-listing.png?auto=format&amp;fit=crop&amp;w=728" data-srcset="https://www.datocms-assets.com/56687/1652231140-bpfdoor-proc-listing.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652231140-bpfdoor-proc-listing.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652231140-bpfdoor-proc-listing.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="Using ls on /proc dir to investigate BPFDoor" /><noscript><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" src="https://www.datocms-assets.com/56687/1652231140-bpfdoor-proc-listing.png?auto=format&amp;fit=crop&amp;w=728" srcSet="https://www.datocms-assets.com/56687/1652231140-bpfdoor-proc-listing.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652231140-bpfdoor-proc-listing.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652231140-bpfdoor-proc-listing.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="Using ls on /proc dir to investigate BPFDoor" /></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}</script></div><span class="ss--image__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></span></div></p><h1>Environment Wipe</h1><p>The last thing the implant does before going fully resident is wipe out the process environment. When you start a process on Linux it stores a lot of useful forensic information in <em>/proc/&lt;PID&gt;/environ. </em>This area can often reveal useful information such as SSH connections that started the process, usernames, etc. </p><p>The environment wipe the implant uses is interesting because it wipes out envp[] (third argument to main() which is where environment variables are passed in as array in Linux). See below for explanation of how to use argv iteration to get environment variables:</p><p><a href="https://stackoverflow.com/questions/31045329/argv-prints-out-environment-variables">argv prints out environment variables</a></p><p>This is a pretty good mechanism and ensures there are no environment variables left on the running process. Although it won't work in this case, we have an article on how to do live process environment forensics here:</p><p><a href="https://www.sandflysecurity.com/blog/using-linux-process-environment-variables-for-live-forensics/">Using Linux Process Environment Variables for Live Forensics</a></p><p>The end result is that the implant leaves the environment completely blank which can happen under some normal circumstances, but usually not. Below we see the fake <em>dbus</em> implant and the real <em>dbus</em> on the same box. The real <em>dbus</em> environment has some data with it. A completely empty environment is unusual for normal processes.</p><p><div ariaRole="button" ariaLabel="Toggle Lightbox" class="ss--image ss--image--elevated ss--image--width-medium ss--image--lightbox"><div data-gatsby-image-wrapper class="gatsby-image-wrapper gatsby-image-wrapper-constrained ss--image__image"><div style="max-width: 728px; display: block;"><img alt role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height='264' width='728' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;" /></div><img aria-hidden="true" data-placeholder-image style="opacity: 1; transition: opacity 500ms linear;" decoding="async" src="" alt /><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" data-src="https://www.datocms-assets.com/56687/1652231905-bpfdoor-fake-dbus-process-environment.png?auto=format&amp;fit=crop&amp;w=728" data-srcset="https://www.datocms-assets.com/56687/1652231905-bpfdoor-fake-dbus-process-environment.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652231905-bpfdoor-fake-dbus-process-environment.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652231905-bpfdoor-fake-dbus-process-environment.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="BPFDoor process environment evasion." /><noscript><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" src="https://www.datocms-assets.com/56687/1652231905-bpfdoor-fake-dbus-process-environment.png?auto=format&amp;fit=crop&amp;w=728" srcSet="https://www.datocms-assets.com/56687/1652231905-bpfdoor-fake-dbus-process-environment.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652231905-bpfdoor-fake-dbus-process-environment.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652231905-bpfdoor-fake-dbus-process-environment.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="BPFDoor process environment evasion." /></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}</script></div><span class="ss--image__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></span></div></p><p><div ariaRole="button" ariaLabel="Toggle Lightbox" class="ss--image ss--image--elevated ss--image--width-medium ss--image--lightbox"><div data-gatsby-image-wrapper class="gatsby-image-wrapper gatsby-image-wrapper-constrained ss--image__image"><div style="max-width: 728px; display: block;"><img alt role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height='264' width='728' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;" /></div><img aria-hidden="true" data-placeholder-image style="opacity: 1; transition: opacity 500ms linear;" decoding="async" src="" alt /><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" data-src="https://www.datocms-assets.com/56687/1652231917-bpfdoor-real-dbus-process-environment.png?auto=format&amp;fit=crop&amp;w=728" data-srcset="https://www.datocms-assets.com/56687/1652231917-bpfdoor-real-dbus-process-environment.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652231917-bpfdoor-real-dbus-process-environment.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652231917-bpfdoor-real-dbus-process-environment.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="Real dbus process environment." /><noscript><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" src="https://www.datocms-assets.com/56687/1652231917-bpfdoor-real-dbus-process-environment.png?auto=format&amp;fit=crop&amp;w=728" srcSet="https://www.datocms-assets.com/56687/1652231917-bpfdoor-real-dbus-process-environment.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652231917-bpfdoor-real-dbus-process-environment.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652231917-bpfdoor-real-dbus-process-environment.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="Real dbus process environment." /></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}</script></div><span class="ss--image__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></span></div></p><h1>BPF Filter Activation and Analysis</h1><p>Once the implant has done its anti-forensics and evasion housekeeping, it goes into the packet capture loop. The packet capture function loads a BPF filter (hence the name). BPF is a highly efficient way to filter packets coming into a system which massively reduces CPU load by preventing all packets from needing to be analyzed by the receiver. It effectively operates as a very efficient pre-filter and only passes likely valid packets for review to the implant.</p><p>With BPFDoor they have taken a BPF filter and converted it to BPF bytecode. This keeps the implant small and less reliant on system libraries that may need to parse a human readable BPF filter, and allows for filters that the normal expression syntax cannot represent.</p><p>We have reverse engineered the bytecode below to show you what it is doing. It does basically two things:</p><ul><li><p>Grabs either an ICMP (ping), UDP or TCP packet.</p></li><li><p>Sees if it has magic data value. If not then reject.</p></li></ul><p>The commented assembly and pseudocode is here:</p><pre><code>l0:     ldh [12]                // A = halfword from offset 12 [Ethernet: EtherType]
l1:     jeq #0x800, l2, l29     // if EtherType==IPv4 goto l2; else goto l29
l2:     ldb [23]                // A = byte from packet offset 23 [IPv4: Protocol]  (data begins at offset 14 of ethernet packet; so this is offset 9 in the IPv4 packet)
l3:     jeq #0x11, l4, l9       // if Protocol==UDP goto l4, else goto l9
l4:     ldh [20]                // A = IPv4 flags+fragment offset
l5:     jset #0x1fff, l29, l6   // ...if fragmentation offset != 0, goto l29
l6:     ldxb 4*([14]&amp;0xf)       // X = IPv4 Header Length
l7:     ldh [x+22]              // A = halfword from offset X+22... first halfword of UDP datagram data
l8:     jeq #0x7255, l28, l29   // if A==0x7255 goto l28, else goto l29
l9:     jeq #0x1, l10, l17      // if Protocol==ICMP goto l10, else goto l17 (jumped to from l3; register contains IP protocol)
l10:    ldh [20]                // A = IPv4 flags+fragment offset
l11:    jset #0x1fff, l29, l12  // ...if fragmentation offset != 0, goto l29
l12:    ldxb 4*([14]&amp;0xf)       // X = IPv4 Header Length
l13:    ldh [x+22]              // A = halfword from offset X+22... first halfword of ICMP data
l14:    jeq #0x7255, l15, l29   // if A==0x7255 goto l15, else goto l29
l15:    ldb [x+14]              // A = byte from offset X+14... ICMP Type
l16:    jeq #0x8, l28, l29      // if ICMP Type == Echo Request (ping) goto l28, else goto l29
l17:    jeq #0x6, l18, l29      // if Protocol==TCP goto l18, else goto l29 (jumped to from l3; register contains IP protocol)
l18:    ldh [20]                // A = IPv4 flags+fragment offset
l19:    jset #0x1fff, l29, l20  // ...if fragmentation offset != 0, goto l29
l20:    ldxb 4*([14]&amp;0xf)       // X = IPv4 Header Length
l21:    ldb [x+26]              // A = byte from offset X+26... Assume no IPv4 options so X=20; packet offset 46 = TCP segment offset 12
l22:    and #0xf0               // A = A &amp; 0xF0 (high nibble of TCP offset 12 = Data offset = TCP header size in 32-bit words)
l23:    rsh #2                  // A = A &gt;&gt; 2 (this has the effect of multiplying the high nibble by four, e.g A&gt;&gt;4 then A&lt;&lt;2). A now contains number of bytes in the TCP header
l24:    add x                   // A = A + X. Adding IPv4 header length + TCP header length.
l25:    tax                     // X = A
l26:    ldh [x+14]              // A = halfword from packet offset X+14 (14 is ethernet header, x is IPv4+TCP header, so this offset is first TCP payload byte)
l27:    jeq #0x5293, l28, l29   // if A==0x5293 goto l28, else goto l29
l28:    ret #0xffff             // return match
l29:    ret #0                  // return doesn't-match

Pseudocode. &quot;return false&quot; means packet doesn't match; &quot;return true&quot; means packet matches.

if (EtherType == IPv4) {
    if (Packet is an additional piece of a fragmented packet)
    {
        return false;
    }
    else
    {
        if (Protocol == UDP &amp;&amp; data[0:2] == 0x7255)
        {
            return true;
        }
        else if (Protocol == ICMP &amp;&amp; data[0:2] == 0x7255 &amp;&amp; ICMP Type == Echo Request)
        {
            return true;
        }
        else if (Protocol == TCP &amp;&amp; data[0:2] == 0x5293)
        {
            return true;
        }
        else {
            return false;
        }
    }
}
else
{
    return false;
}</code></pre><p>To get past the filter you will need to send the right data in the packet as shown above. </p><p>The filter rejects most traffic from entering the main packet decoding loop so the implant will run with very little CPU signature. Packets that make it through the BPF check are quickly checked for a valid password before any further operations take place. </p><h1>Packet Capture and Firewall Bypass</h1><p>The relevance of the BPF filter and packet capture is that it is sniffing traffic at a lower level than the local firewall. <strong>This means that even if you run a firewall the implant will see, and act upon, any magic packet sent to the system</strong><strong><em>. </em></strong>The firewall running on the local host will not block the implant from having this visibility. This is an important point to understand.</p><p>Further, if you have a network perimeter firewall, but it allows traffic to a host on ICMP, UDP or TCP to <strong>any</strong> port, then the implant can see it. Any inbound traffic to the sever can activate the magic packet check and initiate a backdoor.</p><p>For instance, if you run a webserver and lock it down so only port TCP 443 can be accessed, the attacker can send a magic packet to TCP port 443 and activate a backdoor. Same for any UDP packet or even a simple ICMP ping. We'll talk about how it does this below.</p><h1>Locating Packet Sniffing Processes</h1><p>Finding a process sniffing packets on Linux by hand is not always obvious. It's just not normal for most people to check for such things and as a result something like BPFDoor can remain around for a long time unnoticed. </p><p>However, with this malware in a wait state loop searching for packets you can look for traces left under the process stack by viewing <em>/proc/&lt;PID&gt;/stack. </em>With BPFDoor we can see references to function calls in the Linux kernel that indicate the process is likely grabbing packets. </p><p><div ariaRole="button" ariaLabel="Toggle Lightbox" class="ss--image ss--image--elevated ss--image--width-medium ss--image--lightbox"><div data-gatsby-image-wrapper class="gatsby-image-wrapper gatsby-image-wrapper-constrained ss--image__image"><div style="max-width: 728px; display: block;"><img alt role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height='354' width='728' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;" /></div><img aria-hidden="true" data-placeholder-image style="opacity: 1; transition: opacity 500ms linear;" decoding="async" src="" alt /><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" data-src="https://www.datocms-assets.com/56687/1652260269-bpfdoor-stack-packet.png?auto=format&amp;fit=crop&amp;w=728" data-srcset="https://www.datocms-assets.com/56687/1652260269-bpfdoor-stack-packet.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652260269-bpfdoor-stack-packet.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652260269-bpfdoor-stack-packet.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="BPFDoor process stack trace showing packet capture functions calls on Linux." /><noscript><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" src="https://www.datocms-assets.com/56687/1652260269-bpfdoor-stack-packet.png?auto=format&amp;fit=crop&amp;w=728" srcSet="https://www.datocms-assets.com/56687/1652260269-bpfdoor-stack-packet.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652260269-bpfdoor-stack-packet.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652260269-bpfdoor-stack-packet.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="BPFDoor process stack trace showing packet capture functions calls on Linux." /></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}</script></div><span class="ss--image__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></span></div></p><p>You can search the entire <em>/proc/*/stack</em> area for any process that is showing packet capture functions like the above:</p><pre><code>grep packet_recvmsg /proc/*/stack
grep wait_for_more_packets /proc/*/stack</code></pre><p>False alarms with this search are possible, but you can narrow down possible candidates like below. The red arrow is the PID in question running BPFDoor. </p><p><div ariaRole="button" ariaLabel="Toggle Lightbox" class="ss--image ss--image--elevated ss--image--width-medium ss--image--lightbox"><div data-gatsby-image-wrapper class="gatsby-image-wrapper gatsby-image-wrapper-constrained ss--image__image"><div style="max-width: 728px; display: block;"><img alt role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height='103' width='728' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;" /></div><img aria-hidden="true" data-placeholder-image style="opacity: 1; transition: opacity 500ms linear;" decoding="async" src="" alt /><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" data-src="https://www.datocms-assets.com/56687/1652261182-bpfdoor-stack-trace.png?auto=format&amp;fit=crop&amp;w=728" data-srcset="https://www.datocms-assets.com/56687/1652261182-bpfdoor-stack-trace.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652261182-bpfdoor-stack-trace.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652261182-bpfdoor-stack-trace.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="BPFDoor showing packet sniffing function name on Linux." /><noscript><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" src="https://www.datocms-assets.com/56687/1652261182-bpfdoor-stack-trace.png?auto=format&amp;fit=crop&amp;w=728" srcSet="https://www.datocms-assets.com/56687/1652261182-bpfdoor-stack-trace.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652261182-bpfdoor-stack-trace.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652261182-bpfdoor-stack-trace.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="BPFDoor showing packet sniffing function name on Linux." /></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}</script></div><span class="ss--image__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></span></div></p><p>The above is time consuming though and not practical in many cases. Instead, we recommend an automated sweep from Sandfly to quickly identify all processes with packet sockets in operation. With this, BPFDoor is immediately found. The packet capture socket in operation shows up easily and there is no mistaking that this process is reading network traffic.</p><p><div ariaRole="button" ariaLabel="Toggle Lightbox" class="ss--image ss--image--elevated ss--image--width-medium ss--image--lightbox"><div data-gatsby-image-wrapper class="gatsby-image-wrapper gatsby-image-wrapper-constrained ss--image__image"><div style="max-width: 728px; display: block;"><img alt role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height='591' width='728' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;" /></div><img aria-hidden="true" data-placeholder-image style="opacity: 1; transition: opacity 500ms linear;" decoding="async" src="" alt /><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" data-src="https://www.datocms-assets.com/56687/1652259284-bpfdoor-sniffer-tuned-detection.png?auto=format&amp;fit=crop&amp;w=728" data-srcset="https://www.datocms-assets.com/56687/1652259284-bpfdoor-sniffer-tuned-detection.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652259284-bpfdoor-sniffer-tuned-detection.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652259284-bpfdoor-sniffer-tuned-detection.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="BPFDoor sniffer detected." /><noscript><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" src="https://www.datocms-assets.com/56687/1652259284-bpfdoor-sniffer-tuned-detection.png?auto=format&amp;fit=crop&amp;w=728" srcSet="https://www.datocms-assets.com/56687/1652259284-bpfdoor-sniffer-tuned-detection.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652259284-bpfdoor-sniffer-tuned-detection.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652259284-bpfdoor-sniffer-tuned-detection.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="BPFDoor sniffer detected." /></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}</script></div><span class="ss--image__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></span></div></p><p><div ariaRole="button" ariaLabel="Toggle Lightbox" class="ss--image ss--image--elevated ss--image--width-medium ss--image--lightbox"><div data-gatsby-image-wrapper class="gatsby-image-wrapper gatsby-image-wrapper-constrained ss--image__image"><div style="max-width: 728px; display: block;"><img alt role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height='542' width='728' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;" /></div><img aria-hidden="true" data-placeholder-image style="opacity: 1; transition: opacity 500ms linear;" decoding="async" src="" alt /><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" data-src="https://www.datocms-assets.com/56687/1652259309-bpfdoor-packet-socket.png?auto=format&amp;fit=crop&amp;w=728" data-srcset="https://www.datocms-assets.com/56687/1652259309-bpfdoor-packet-socket.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652259309-bpfdoor-packet-socket.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652259309-bpfdoor-packet-socket.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="packet capture socket type detected with BPFDoor" /><noscript><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" src="https://www.datocms-assets.com/56687/1652259309-bpfdoor-packet-socket.png?auto=format&amp;fit=crop&amp;w=728" srcSet="https://www.datocms-assets.com/56687/1652259309-bpfdoor-packet-socket.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652259309-bpfdoor-packet-socket.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652259309-bpfdoor-packet-socket.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="packet capture socket type detected with BPFDoor" /></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}</script></div><span class="ss--image__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></span></div></p><p></p><h1>RC4 Encryption and Passwords</h1><p>To access the implant you need not just a magic packet, but also the correct password. The leaked source has some passwords set, but there is no reason to believe these are used in actual deployment. </p><p>The implant uses RC4 as the encryption layer. RC4 is a very robust cipher for this application and is the only truly secure cipher you can write on a napkin. It's a great choice for small implant code like this. </p><p>In the case of the implant we will deduct a few points because they did not throw out the first few kilobytes from the cipher stream which can weaken it, but overall this cipher is a good choice to keep things small and fast. </p><p>The implant can take an optional password. The password is compared against two internal values. If it matches one value it will setup a local bindshell backdoor. If it matches another it will do a reverse bindshell connect-back to the specified host and port. </p><p>There is a third option though and that is if no password is specified, then a function is called that sends a single UDP packet with the value &quot;1&quot;. This might be some kind of operation check status to show the implant is still running. Relevant code below:</p><pre><code>if ((s_len = sendto(sock, &quot;1&quot;, 1, 0, (struct sockaddr *)&amp;remote, sizeof(struct sockaddr))) &lt; 0) {
                close(sock);
                return -1;
        }</code></pre><p>Note the above is not passed through the RC4 encryption. If you are investigating this on your network, it may be worthwhile looking for single UDP packets with just the data &quot;1&quot; in them and nothing else from many hosts over time to a single host IP (controller).</p><h1>Firewall Bypass for Bindshell Backdoor</h1><p>The implant has a unique feature to bypass the host firewall and make the traffic look legitimate. When the magic packet is received by the host, the implant will spawn a new instance and change the local <em>iptables</em> rules to do a redirect from the requesting host to the shell port. </p><p>For instance, the implant can redirect all traffic from the attacker using TCP port 443 (encrypted web) to the shell. Externally, the traffic will look like TLS/SSL traffic but in fact the attacker is interacting with a remote <em>root</em> shell on the system.</p><p>Let's review what this means with a diagram:</p><p><div ariaRole="button" ariaLabel="Toggle Lightbox" class="ss--image ss--image--elevated ss--image--width-medium ss--image--lightbox"><div data-gatsby-image-wrapper class="gatsby-image-wrapper gatsby-image-wrapper-constrained ss--image__image"><div style="max-width: 728px; display: block;"><img alt role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height='409' width='728' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;" /></div><img aria-hidden="true" data-placeholder-image style="opacity: 1; transition: opacity 500ms linear;" decoding="async" src="" alt /><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" data-src="https://www.datocms-assets.com/56687/1652238177-firewall-redirect-diagram.png?auto=format&amp;fit=crop&amp;w=728" data-srcset="https://www.datocms-assets.com/56687/1652238177-firewall-redirect-diagram.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652238177-firewall-redirect-diagram.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652238177-firewall-redirect-diagram.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="BPFDoor Firewall Redirect/Bypass" /><noscript><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" src="https://www.datocms-assets.com/56687/1652238177-firewall-redirect-diagram.png?auto=format&amp;fit=crop&amp;w=728" srcSet="https://www.datocms-assets.com/56687/1652238177-firewall-redirect-diagram.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652238177-firewall-redirect-diagram.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652238177-firewall-redirect-diagram.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="BPFDoor Firewall Redirect/Bypass" /></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}</script></div><span class="ss--image__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></span></div></p><p>The steps are as follows if the actor requests the system open a local shell:</p><p>1) Implant is listening to all traffic coming to the host regardless of firewall.</p><p>2) Implant sees magic packet.</p><p>3) Magic packet can contain IP address, port and password for attacker. Otherwise it uses the origin IP address.</p><p>4) Depending on password, implant will open local or connect-back backdoor.</p><p>5) Implant selects a TCP port sequentially starting at 42391 up to 43391. </p><p>6) Implant binds to first unused port in this range. </p><p>7) For local shell, <em>iptables</em> is called to redirect all traffic from attacker host IP from the requested port to the bound port range from the above steps.</p><p>8) Attacker connects with TCP to the defined port they requested (e.g. TCP port 443). </p><p>9) Traffic from that host is redirected from the port to the shell routing behind the firewall.</p><p>10) Observed traffic still appears to be going to host on a legitimate port, but in fact is being routed to the shell on the host.</p><p>If this is confusing, then let's look at the shell in action using SSH as our target port. </p><p><strong>NOTE: We disabled the RC4 encryption in the implant for example purposes to use </strong><em><strong>netcat</strong></em><strong>. The real implant would require the correct password and RC4 encryption layer to see these results.</strong></p><p>Below we connect to a host on SSH port 22. We get back a normal OpenSSH banner. Then on another window we send the magic packet on UDP to the host (or TCP or ICMP). The implant sees this packet and that we want to use TCP port 22 as our shell access port. The implant starts a shell on a high TCP port and then redirects the traffic. When we connect again to port 22, instead of SSH we now get a shell with <em>root</em> access. </p><p>Here again is the important point: <strong>All other users still get SSH. Only the attacker's traffic is redirected to the shell even though it goes to the same SSH port!</strong></p><p><div ariaRole="button" ariaLabel="Toggle Lightbox" class="ss--image ss--image--elevated ss--image--width-medium ss--image--lightbox"><div data-gatsby-image-wrapper class="gatsby-image-wrapper gatsby-image-wrapper-constrained ss--image__image"><div style="max-width: 728px; display: block;"><img alt role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height='364' width='728' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;" /></div><img aria-hidden="true" data-placeholder-image style="opacity: 1; transition: opacity 500ms linear;" decoding="async" src="" alt /><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" data-src="https://www.datocms-assets.com/56687/1652238590-bpf-ssh-shell-activation-edited.png?auto=format&amp;fit=crop&amp;w=728" data-srcset="https://www.datocms-assets.com/56687/1652238590-bpf-ssh-shell-activation-edited.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652238590-bpf-ssh-shell-activation-edited.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652238590-bpf-ssh-shell-activation-edited.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="BPFDoor Backdoor Operation" /><noscript><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" src="https://www.datocms-assets.com/56687/1652238590-bpf-ssh-shell-activation-edited.png?auto=format&amp;fit=crop&amp;w=728" srcSet="https://www.datocms-assets.com/56687/1652238590-bpf-ssh-shell-activation-edited.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652238590-bpf-ssh-shell-activation-edited.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652238590-bpf-ssh-shell-activation-edited.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="BPFDoor Backdoor Operation" /></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}</script></div><span class="ss--image__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></span></div></p><p>You'll see also when you connect the value &quot;3458&quot; is sent above. This may be a version identifier for the implant operator.</p><p>The redirect rules for the shell access are seen below. Here you see that the TCP port 42392 was found available and the shell bound to it. All TCP port 22 traffic from our attacker host (192.168.1.1) is now routed to this shell on this port. The traffic looks like encrypted SSH communications going to TCP port 22, but in reality is being directed to the shell port once it hits the <em>iptables</em> rule for the attacker host <em>only.</em></p><pre><code>/sbin/iptables -t nat -D PREROUTING -p tcp -s 192.168.1.1 --dport 22 -j REDIRECT --to-ports 42392
/sbin/iptables -D INPUT -p tcp -s 192.168.1.1 -j ACCEPT</code></pre><h1>Connect-Back Bindshell</h1><p>The implant also has the ability to connect back to a host as defined in the magic packet. Operation here is largely the same, but this may not be as stealthy having a system connect outbound (and many orgs may block servers talking outbound). The first method of packet redirect is far more dangerous and harder to find as it will look like legitimate traffic going to the server and not originating outbound.</p><h1>Status Check</h1><p>As discussed above, if you do not supply any password or an incorrect password in a magic packet the implant will simply send out &quot;1&quot; on UDP. We believe this is some kind of status check to allow keeping tabs on many systems.</p><p><strong>Organizations may want to consider running a network scan against their hosts sending a magic packet on ICMP, UDP or TCP with a known UDP port you monitor to see if any systems respond. </strong>Any host responding has an active implant.</p><h1>Shell Anti-Forensics and Evasion</h1><p>The shell is spawned by forking a controller and finally the shell itself. The controlling PID will be masquerading running under the name:</p><p><em>/usr/libexec/postfix/master </em></p><p>The shell itself will be running under the name:</p><p><em>qmgr -l -t fifo -u</em></p><p>In the <em>ps </em>listing you'll see the following. Here the implant is restarted under a new bogus name. Then you see the two processes masking the shell operation when it is operating.</p><p><div ariaRole="button" ariaLabel="Toggle Lightbox" class="ss--image ss--image--elevated ss--image--width-medium ss--image--lightbox"><div data-gatsby-image-wrapper class="gatsby-image-wrapper gatsby-image-wrapper-constrained ss--image__image"><div style="max-width: 728px; display: block;"><img alt role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height='283' width='728' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;" /></div><img aria-hidden="true" data-placeholder-image style="opacity: 1; transition: opacity 500ms linear;" decoding="async" src="" alt /><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" data-src="https://www.datocms-assets.com/56687/1652239393-bpfdoor-ps-listing-shell-running.png?auto=format&amp;fit=crop&amp;w=728" data-srcset="https://www.datocms-assets.com/56687/1652239393-bpfdoor-ps-listing-shell-running.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652239393-bpfdoor-ps-listing-shell-running.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652239393-bpfdoor-ps-listing-shell-running.png?auto=format&amp;fit=crop&amp;w=728 728w" alt /><noscript><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" src="https://www.datocms-assets.com/56687/1652239393-bpfdoor-ps-listing-shell-running.png?auto=format&amp;fit=crop&amp;w=728" srcSet="https://www.datocms-assets.com/56687/1652239393-bpfdoor-ps-listing-shell-running.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652239393-bpfdoor-ps-listing-shell-running.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652239393-bpfdoor-ps-listing-shell-running.png?auto=format&amp;fit=crop&amp;w=728 728w" alt /></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}</script></div><span class="ss--image__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></span></div></p><p>Again if you go under <em>/proc/&lt;PID&gt;</em> and do a listing you will see the reference to the real names. </p><p>Sandfly hunter view shows the mismatch between the shell and the masquerading names it is using. Here the masquerading name clearly does not match the shell path and actual process name we saw. </p><p><div ariaRole="button" ariaLabel="Toggle Lightbox" class="ss--image ss--image--elevated ss--image--width-medium ss--image--lightbox"><div data-gatsby-image-wrapper class="gatsby-image-wrapper gatsby-image-wrapper-constrained ss--image__image"><div style="max-width: 728px; display: block;"><img alt role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height='402' width='728' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;" /></div><img aria-hidden="true" data-placeholder-image style="opacity: 1; transition: opacity 500ms linear;" decoding="async" src="" alt /><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" data-src="https://www.datocms-assets.com/56687/1652239621-bpfdoor-dash-shell-hunter-points.png?auto=format&amp;fit=crop&amp;w=728" data-srcset="https://www.datocms-assets.com/56687/1652239621-bpfdoor-dash-shell-hunter-points.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652239621-bpfdoor-dash-shell-hunter-points.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652239621-bpfdoor-dash-shell-hunter-points.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="Sandfly shows real name of BPFDoor bindshell." /><noscript><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" src="https://www.datocms-assets.com/56687/1652239621-bpfdoor-dash-shell-hunter-points.png?auto=format&amp;fit=crop&amp;w=728" srcSet="https://www.datocms-assets.com/56687/1652239621-bpfdoor-dash-shell-hunter-points.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652239621-bpfdoor-dash-shell-hunter-points.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652239621-bpfdoor-dash-shell-hunter-points.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="Sandfly shows real name of BPFDoor bindshell." /></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}</script></div><span class="ss--image__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></span></div></p><p>The shell also sets up some anti-forensics for good measure. The environment is carefully selected to only have the following. We'll use <em>strings /proc/&lt;PID&gt;/environ</em> to look at what it is doing below:</p><pre><code>root@bpfdoor:/# strings /proc/2500/environ
HOME=/tmp
PS1=[\u@\h \W]\\$ 
HISTFILE=/dev/null
MYSQL_HISTFILE=/dev/null
PATH=/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/X11R6/bin:./bin
vt100
</code></pre><p>The implant is telling the shell to not log shell history and also does the same for MySQL. This means that the operators likely are doing a lot of work with MySQL to call this out specifically. The listing of kerberos in the path also means that kerberos authentication systems may be a frequent target.</p><p>Sandfly finds this shell in numerous ways, but the anti-forensics is a dead giveaway it's up to no good.</p><p><div ariaRole="button" ariaLabel="Toggle Lightbox" class="ss--image ss--image--elevated ss--image--width-medium ss--image--lightbox"><div data-gatsby-image-wrapper class="gatsby-image-wrapper gatsby-image-wrapper-constrained ss--image__image"><div style="max-width: 728px; display: block;"><img alt role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height='569' width='728' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;" /></div><img aria-hidden="true" data-placeholder-image style="opacity: 1; transition: opacity 500ms linear;" decoding="async" src="" alt /><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" data-src="https://www.datocms-assets.com/56687/1652240076-bpfdoor-anti-forensics-shell.png?auto=format&amp;fit=crop&amp;w=728" data-srcset="https://www.datocms-assets.com/56687/1652240076-bpfdoor-anti-forensics-shell.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652240076-bpfdoor-anti-forensics-shell.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652240076-bpfdoor-anti-forensics-shell.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="BPFDoor anti-forensics seen by Sandfly." /><noscript><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" src="https://www.datocms-assets.com/56687/1652240076-bpfdoor-anti-forensics-shell.png?auto=format&amp;fit=crop&amp;w=728" srcSet="https://www.datocms-assets.com/56687/1652240076-bpfdoor-anti-forensics-shell.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652240076-bpfdoor-anti-forensics-shell.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652240076-bpfdoor-anti-forensics-shell.png?auto=format&amp;fit=crop&amp;w=728 728w" alt="BPFDoor anti-forensics seen by Sandfly." /></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}</script></div><span class="ss--image__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></span></div></p><h1>Implant Termination</h1><p>The implant has mechanisms to terminate itself if there is an error or for other reasons. It will clean up its dropper file and exit cleanly. There are no destructive commands built into the implant, but obviously a <em>root</em> shell is all you need. </p><h1>Sandfly Detection</h1><p>Although the implant takes many measures to hide, it is easily found if you know where and how to look. Sandfly finds it easily and would have been able to for quite a while now. </p><p>A host running this backdoor will have many distinct and very severe Sandfly alerts that something is wrong. Although the techniques here will help incident responders investigate their hosts by hand, we offer a <a href="https://www.sandflysecurity.com/get-sandfly/">free 500 host license </a>for Sandfly that will do it much faster and more completely. </p><p><div ariaRole="button" ariaLabel="Toggle Lightbox" class="ss--image ss--image--elevated ss--image--width-medium ss--image--lightbox"><div data-gatsby-image-wrapper class="gatsby-image-wrapper gatsby-image-wrapper-constrained ss--image__image"><div style="max-width: 728px; display: block;"><img alt role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height='326' width='728' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;" /></div><img aria-hidden="true" data-placeholder-image style="opacity: 1; transition: opacity 500ms linear;" decoding="async" src="" alt /><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" data-src="https://www.datocms-assets.com/56687/1652241169-bpfdoor-alerts.png?auto=format&amp;fit=crop&amp;w=728" data-srcset="https://www.datocms-assets.com/56687/1652241169-bpfdoor-alerts.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652241169-bpfdoor-alerts.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652241169-bpfdoor-alerts.png?auto=format&amp;fit=crop&amp;w=728 728w" alt /><noscript><img data-gatsby-image-ssr data-main-image style="opacity: 0;" sizes="(min-width: 728px) 728px, 100vw" decoding="async" loading="lazy" src="https://www.datocms-assets.com/56687/1652241169-bpfdoor-alerts.png?auto=format&amp;fit=crop&amp;w=728" srcSet="https://www.datocms-assets.com/56687/1652241169-bpfdoor-alerts.png?auto=format&amp;dpr=0.25&amp;fit=crop&amp;w=728 182w,https://www.datocms-assets.com/56687/1652241169-bpfdoor-alerts.png?auto=format&amp;dpr=0.5&amp;fit=crop&amp;w=728 364w,https://www.datocms-assets.com/56687/1652241169-bpfdoor-alerts.png?auto=format&amp;fit=crop&amp;w=728 728w" alt /></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}</script></div><span class="ss--image__icon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg></span></div></p><h1>Conclusions</h1><p>This implant is well executed and layers known-tactics such as environment anti-forensics, timestomping, and process masquerading effectively. The use of BPF and packet capture provides a way to bypass local firewalls to allow remote attackers to control the implant. Finally, the redirect feature is unique and very dangerous as it can make malicious traffic blend in seamlessly with legitimate traffic on an infected host with exposed ports to the internet.</p><p>The code does not reveal much about the authors, but it clearly was done by someone that knows what they are doing with an intent to remain undetected.</p><h1>Indicators of Compromise</h1><p>Use these to help manually search for BPFDoor. Please see our<a href="https://www.sandflysecurity.com/blog/compromised-linux-cheat-sheet/"> Linux compromise cheat sheet</a> for commands to help you with these checks.</p><p><strong>Do not use hashes to find this malware.</strong> Hashes work very poorly on Linux to find malware as the binaries are easily re-compiled and changed. This kind of malware needs tactics hunting to find it consistently.</p><h2>Hunting Tactics</h2><p>Possible binary left behind if implant fails to load:</p><pre><code>/dev/shm/kdmtmpflush </code></pre><p>Dropper if implant active or did not clean up:</p><pre><code>/var/run/haldrund.pid </code></pre><p>Deleted process called <em>kdmtmpflush</em> or similar. </p><p>Processes missing environment variables.</p><p>Any process running from <em>/dev/shm </em></p><p>Any process operating with a packet socket open that you don't recognize as needing that kind of access.</p><p>Process stack trace showing kernel function calls involved with packet capture:</p><pre><code>grep packet_recvmsg /proc/*/stack
grep wait_for_more_packets /proc/*/stack</code></pre><p>Unusual redirect rules in <em>iptables</em>. </p><p>Any process bound to TCP port 42391-43391 as a listening service.</p><p>System boot scripts referencing unusual binaries or strange path locations.</p><p>UDP outbound traffic containing only the data &quot;1&quot; perhaps from many hosts back to a single IP for status checks.</p><p>Low bandwidth intermittent data streams to ports where you'd expect high traffic. For instance someone using an interactive shell sending manual commands with long latency between packets (e.g. using a bindshell backdoor) would be an unusual pattern on a webserver pushing big data over TCP port 443 to web browsers.</p><div class="ss--spacer "></div></div><div class="ss--content ss--content--gutters ss--content--text-align-left ss--content--width-small"><div class="ss--share"><h4 class="ss--share__heading">Share this:</h4><div class="ss--share__icons"><button aria-label="facebook" style="background-color: transparent; border: none; padding: 0px; font: inherit; color: inherit; cursor: pointer;" class="react-share__ShareButton"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 448 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M400 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h137.25V327.69h-63V256h63v-54.64c0-62.15 37-96.48 93.67-96.48 27.14 0 55.52 4.84 55.52 4.84v61h-31.27c-30.81 0-40.42 19.12-40.42 38.73V256h68.78l-11 71.69h-57.78V480H400a48 48 0 0 0 48-48V80a48 48 0 0 0-48-48z"></path></svg></button><button aria-label="linkedin" style="background-color: transparent; border: none; padding: 0px; font: inherit; color: inherit; cursor: pointer;" class="react-share__ShareButton"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 448 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"></path></svg></button><button aria-label="twitter" style="background-color: transparent; border: none; padding: 0px; font: inherit; color: inherit; cursor: pointer;" class="react-share__ShareButton"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 448 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-48.9 158.8c.2 2.8.2 5.7.2 8.5 0 86.7-66 186.6-186.6 186.6-37.2 0-71.7-10.8-100.7-29.4 5.3.6 10.4.8 15.8.8 30.7 0 58.9-10.4 81.4-28-28.8-.6-53-19.5-61.3-45.5 10.1 1.5 19.2 1.5 29.6-1.2-30-6.1-52.5-32.5-52.5-64.4v-.8c8.7 4.9 18.9 7.9 29.6 8.3a65.447 65.447 0 0 1-29.2-54.6c0-12.2 3.2-23.4 8.9-33.1 32.3 39.8 80.8 65.8 135.2 68.6-9.3-44.5 24-80.6 64-80.6 18.9 0 35.9 7.9 47.9 20.7 14.8-2.8 29-8.3 41.6-15.8-4.9 15.2-15.2 28-28.8 36.1 13.2-1.4 26-5.1 37.8-10.2-8.9 13.1-20.1 24.7-32.9 34z"></path></svg></button></div></div></div><div class="ss--spacer ss--spacer--padding-double"></div><div class="ss--cta ss--cta--variant-default ss--cta--color-default"><div><div class="ss--cta__content"><h2>Let Sandfly keep your Linux systems secure.</h2><a class="ss--button ss--button--alignment-center ss--button--color-secondary ss--button--elevated ss--button--style-solid" href="/get-sandfly/"><span>Learn More</span></a></div></div></div></main></div><footer class="ss--footer"><div class="ss--footer__container"><div class="ss--footer__wrapper"><div class="ss--footer__menu"><div class="ss--footer__menu-heading"><h4>Contact Us</h4></div><ul><li><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z"></path></svg><a href="tel:+64 3 3792313">+64 3 3792313</a></li><li><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M20.5 3l-.16.03L15 5.1 9 3 3.36 4.9c-.21.07-.36.25-.36.48V20.5c0 .28.22.5.5.5l.16-.03L9 18.9l6 2.1 5.64-1.9c.21-.07.36-.25.36-.48V3.5c0-.28-.22-.5-.5-.5zM15 19l-6-2.11V5l6 2.11V19z"></path></svg><a href="https://goo.gl/maps/9cFto1o6GNa9RK6S9" target="_blank" rel="noopener noreferrer">4 Ash Street Christchurch, New Zealand 8011</a></li></ul></div><div class="ss--footer__menu"><div class="ss--footer__menu-heading"><h4>Product Navigation</h4></div><ul><li><a href="/platform/why-sandfly/">Why Sandfly?</a></li><li><a href="/platform/how-sandfly-works/">How Sandfly Works</a></li><li><a href="/platform/threats-detected/">Linux Threats Detected</a></li><li><a href="/platform/walk-through/">Walk Through</a></li></ul></div><div class="ss--footer__menu"><div class="ss--footer__menu-heading"><h4>General Navigation</h4></div><ul><li><a href="/about-us/our-story/">Our Story</a></li><li><a href="/about-us/partner/">Partners And MSSPs</a></li><li><a href="/under-attack/">Under Attack? </a></li><li><a href="/contact-us/">Contact Us </a></li></ul></div><div class="ss--footer__menu"><div class="ss--footer__menu-heading"><h4>Keep in Touch</h4></div><form class='ss--form' id='Newsletter' method='POST' name='Newsletter'><div style="opacity: 1; transform: none;"><div><fieldset><input type="hidden" name="form-name" value="Newsletter" /><div class="ss--input "><label for="input--firstName">First Name<span area-label="required">*</span></label><input id="input--firstName" name="firstName" placeholder="First Name" required type="text" /></div><div class="ss--input "><label for="input--lastName">Last Name<span area-label="required">*</span></label><input id="input--lastName" name="lastName" placeholder="Last Name" required type="text" /></div><div class="ss--input "><label for="input--emailAddress">Email Address<span area-label="required">*</span></label><input id="input--emailAddress" name="emailAddress" placeholder="Email Address" required type="email" /></div><button type="submit" class="ss--button ss--button--alignment-left ss--button--color-primary ss--button--elevated ss--button--style-solid ss--button--width-full"><span>Submit</span></button></fieldset></div></div></form></div><div class="ss--footer__menu"><div class="ss--footer__menu-heading"><h4>Connect With Us</h4></div><ul class="ss--footer__social"><li><a target="_blank" rel="noopener noreferrer" href="https://twitter.com/sandflysecurity"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"></path></svg></a></li><li><a target="_blank" rel="noopener noreferrer" href="https://nz.linkedin.com/company/sandfly"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 448 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"></path></svg></a></li><li><a target="_blank" rel="noopener noreferrer" href="/blog/rss.xml"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 448 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M128.081 415.959c0 35.369-28.672 64.041-64.041 64.041S0 451.328 0 415.959s28.672-64.041 64.041-64.041 64.04 28.673 64.04 64.041zm175.66 47.25c-8.354-154.6-132.185-278.587-286.95-286.95C7.656 175.765 0 183.105 0 192.253v48.069c0 8.415 6.49 15.472 14.887 16.018 111.832 7.284 201.473 96.702 208.772 208.772.547 8.397 7.604 14.887 16.018 14.887h48.069c9.149.001 16.489-7.655 15.995-16.79zm144.249.288C439.596 229.677 251.465 40.445 16.503 32.01 7.473 31.686 0 38.981 0 48.016v48.068c0 8.625 6.835 15.645 15.453 15.999 191.179 7.839 344.627 161.316 352.465 352.465.353 8.618 7.373 15.453 15.999 15.453h48.068c9.034-.001 16.329-7.474 16.005-16.504z"></path></svg></a></li></ul></div></div><div class="ss--copyright"><p>© 2022 Sandfly Security, Ltd. <a class="ss--copyright__link" href="/privacy-policy/">Terms &amp; Privacy Policy</a></p></div></div></footer><script type="application/ld+json">{"@context":"https://schema.org","@type":"Organization","name":"Sandfly Security","description":"Sandfly is an agentless Linux endpoint intrusion detection and incident response platform. Sandfly is a Linux network and server security monitoring tool. Sandfly finds malware and intruders on Linux without agents.","email":"support@sandflysecurity.com","contactPoint":[{"@type":"ContactPoint","email":"support@sandflysecurity.com","contactType":"customer service"}],"url":"https://www.sandflysecurity.com","logo":"/icon.svg","sameAs":["https://www.facebook.com/sandflysec","https://twitter.com/sandflysecurity"]}</script></div></div><div id="gatsby-announcer" style="position: absolute; top: 0px; width: 1px; height: 1px; padding: 0px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0px;" aria-live="assertive" aria-atomic="true"></div></div><script async src="https://www.googletagmanager.com/gtag/js?id=G-D2N4MNQFQ1"></script><script>
      
      
      if(!(navigator.doNotTrack == "1" || window.doNotTrack == "1")) {
        window.dataLayer = window.dataLayer || [];
        function gtag(){window.dataLayer && window.dataLayer.push(arguments);}
        gtag('js', new Date());

        gtag('config', 'G-D2N4MNQFQ1', {"send_page_view":false});
      }
      </script><script type="text/javascript" id="hs-script-loader" async defer src="//js.hs-scripts.com/4661162.js"></script><script>var _hsq = window._hsq = window._hsq || [];_hsq.push(['setPath', window.location.pathname + window.location.search + window.location.hash]);if (window.doNotTrack || navigator.doNotTrack || navigator.msDoNotTrack || 'msTrackingProtectionEnabled' in window.external) {if (window.doNotTrack == '1' || navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1' || window.external.msTrackingProtectionEnabled()) {_hsq.push(['doNotTrack']);}}</script><script id="gatsby-script-loader">/*<![CDATA[*/window.pagePath="/blog/bpfdoor-an-evasive-linux-backdoor-technical-analysis/";/*]]>*/</script><script id="gatsby-chunk-mapping">/*<![CDATA[*/window.___chunkMapping={"polyfill":["/polyfill-424d8cf679ed3ce4fef3.js"],"app":["/app-48ae15cb23f3d89f16ff.js"],"reactPlayerYouTube":["/reactPlayerYouTube-3329d573b91aa19b5897.js"],"reactPlayerSoundCloud":["/reactPlayerSoundCloud-c72ecb0a2b3a4e3629bf.js"],"reactPlayerVimeo":["/reactPlayerVimeo-31f229efd34b80184999.js"],"reactPlayerFacebook":["/reactPlayerFacebook-5494d99e0dad3b8e2de6.js"],"reactPlayerStreamable":["/reactPlayerStreamable-d9073ebadcf66ae721bf.js"],"reactPlayerWistia":["/reactPlayerWistia-4dcf45af69fc7389cfe7.js"],"reactPlayerTwitch":["/reactPlayerTwitch-47d4c0375028114b7701.js"],"reactPlayerDailyMotion":["/reactPlayerDailyMotion-921554832fa11a162efe.js"],"reactPlayerMixcloud":["/reactPlayerMixcloud-8c902e33d00f5068751a.js"],"reactPlayerVidyard":["/reactPlayerVidyard-987f0a9056ec4b98cb3c.js"],"reactPlayerKaltura":["/reactPlayerKaltura-514612e2d08eba4c2d13.js"],"reactPlayerFilePlayer":["/reactPlayerFilePlayer-6a8e81ca88f21726a1bc.js"],"reactPlayerPreview":["/reactPlayerPreview-7caff614a9d717a06536.js"],"component---src-pages-styleguide-tsx":["/component---src-pages-styleguide-tsx-7a5c61e43122701be937.js"],"component---src-templates-case-studies-tsx":["/component---src-templates-case-studies-tsx-721c423c00ac0ed02e80.js"],"component---src-templates-case-study-tsx":["/component---src-templates-case-study-tsx-b681d791603420439c4d.js"],"component---src-templates-page-tsx":["/component---src-templates-page-tsx-837e04fc5b115150878c.js"],"component---src-templates-post-list-tsx":["/component---src-templates-post-list-tsx-b23bc2743f0627227e9c.js"],"component---src-templates-post-tag-tsx":["/component---src-templates-post-tag-tsx-fb76324e711ebd5e74d3.js"],"component---src-templates-post-tsx":["/component---src-templates-post-tsx-c16b4e12703eba509130.js"],"component---src-templates-pricing-tsx":["/component---src-templates-pricing-tsx-d0404d9eaae42f5c989e.js"]};/*]]>*/</script><script src="/polyfill-424d8cf679ed3ce4fef3.js" noModule></script><script src="/component---src-templates-post-tsx-c16b4e12703eba509130.js" async></script><script src="/commons-f9f5fcc60d25b105667f.js" async></script><script src="/app-48ae15cb23f3d89f16ff.js" async></script><script src="/dc6a8720040df98778fe970bf6c000a41750d3ae-9658f7f752126de65529.js" async></script><script src="/d7eeaac4-9c0e24a908780f8d6714.js" async></script><script src="/0c428ae2-8cfc58f9628708c73fdf.js" async></script><script src="/1bfc9850-8f7c3f76a08c2178042b.js" async></script><script src="/545f34e4-222e9b8aec85efb6ec28.js" async></script><script src="/252f366e-4458bcdf9678f3e5d264.js" async></script><script src="/framework-37f3235980163f3a0502.js" async></script><script src="/webpack-runtime-7a237243913e1c3537fa.js" async></script></body></html>